处理react-native-swiper第三方轮播组件的样式高度问题,方案是将swiper组件放到一个View容器里,并且给容器设定高度,超出部分overflow: hidden
如果需要在轮播图上放标题+横向长条背景框,则需要放到容器之外,进行绝对定位,而且swiper组件有高度问题,需要注意不要添加多余的marginTop、paddingTop、height等高度值,容器检查元素的时候晕头转向,因为在ios模拟器中,并不是所有元素都能检查到!
参考如下代码:
/**
* @flow
* @description
* @author huangzhixin@yodinfo.com
*/
import React from "react";
import {
View,
FlatList,
RefreshControl,
ScrollView,
Image,
DeviceEventEmitter,
TouchableOpacity,
Text,
StyleSheet,
StatusBar,
Platform,
Dimensions,
WebView
} from "react-native";
import BaseScene from "../../base/BaseScene";
import { ImagePlaceholder } from "../../base/PlaceholderContainer";
import LoadingView from "../../widget/LoadingView";
import { TabBar } from "../../components/tabs/TabBarBase";
import OAColor from "../../theme/OAColor";
import OAStyles from "../../theme/OAStyles";
import {
NAVBAR_HEIGHT,
PageStatusView,
CustomNav,
SectionItem
} from "../../components";
import {
LoadStatus,
getErrorStatus,
isErrorStatus,
startTrace,
trace,
executeHomeDelay,
addStoreValue,
envDict
} from "../../common";
import { HomeNormalHead, HomeNormalNav, HomeTitleItem } from "./components";
// import { login } from '../../services/app';
import WhiteSpace from "../../widget/WhiteSpace";
import Swiper from "react-native-swiper";
import CustomNavIcon from "./components/CustomNavIcon";
import OASize from "../../constants/OASize";
import HomeNewsItem from "./components/HomeNewsItem";
import { NoticeBar } from "antd-mobile";
import IconView from "../../widget/IconView";
import OAVariables from "../../constants/OAVariables";
import RefreshPageContainer from "../../base/RefreshPageContainer";
import { getRecentNewsList } from "../../services/home";
type Props = {};
type State = {};
declare var mb: any;
const scrollRange = 95;
const navArray = [
require("../../assets/home/ic_1.png"),
require("../../assets/home/ic_2.png"),
require("../../assets/home/ic_3.png"),
require("../../assets/home/ic_4.png")
];
export default class HomeContainer extends BaseScene<Props, State> {
props: Props;
state: State;
constructor(props: Props) {
super(props);
this.state = {
iconAlpha: 0,
isRefreshing: false,
taskDto: {},
flowDto: {},
loadStatus: LoadStatus.Loading,
showFake: false,
isMain: true,
visitPlanDto: {},
initialized: false,
loginError: false,
selectedTab: "home",
refreshing: false
};
this.alreadyLoad = false;
this.isLoading = false;
this.scrollHeight = scrollRange;
this.mDelayTask = 0;
this.mShadowTop = 0;
this.mCenterTop = 0;
this.mScrollHeight = 0;
}
componentWillMount = () => {
const { parentRef } = this.props;
mb(parentRef).hideNav();
// super.executeOnLoad(this.login);
};
// login = async () => {
// const callback = () => {
// this.setState({
// initialized: true,
// loginError: false
// });
// this.fetchData();
// };
// // 如果不是在OA环境 直接登录
// // 如果在OA环境且不是测试环境 那么使用username登录
// const fetch = !mb.getMainProjectParams()
// ? () => {
// return login('ims_admin');
// }
// : async () => {
// const { username } = await mb.getMainProjectParams();
// return envDict.development ? login('ims_admin') : login(username);
// };
// try {
// const { token } = await fetch();
// addStoreValue('token', token).then(callback);
// } catch (e) {
// this.setState({
// loginError: true
// });
// }
// };
componentDidMount() {}
componentWillUnmount() {}
onTabClick = () => {
this.scrollToTop();
};
renderSwiper = () => {
return (
<View
style={{
flex: 1,
height: OASize(240),
overflow: "hidden"
}}
>
<Swiper
loop={true} //如果设置为false,那么滑动到最后一张时,再次滑动将不会滑到第一张图片。
autoplay={true} //自动轮播
autoplayTimeout={1} //每隔4秒切换
horizontal={true} //水平方向,为false可设置为竖直方向
// paginationStyle={{ bottom: 0 }} //小圆点的位置:距离底部10px
showsButtons={false} //为false时不显示控制按钮
showsPagination={true} //为false不显示下方圆点
// top={NAVBAR_HEIGHT}
dot={
<View
style={{
//未选中的圆点样式
backgroundColor: OAColor.swiperDot,
width: OASize(5),
height: OASize(5),
borderRadius: OASize(2.5),
marginHorizontal: OASize(5)
}}
/>
}
activeDot={
<View
style={{
//选中的圆点样式
backgroundColor: OAColor.activeDot,
width: OASize(5),
height: OASize(5),
borderRadius: OASize(2.5),
marginHorizontal: OASize(5)
}}
/>
}
>
<Image
style={{
flex: 1,
justifyContent: "center",
alignItems: "center"
}}
source={require("./img/banner01.png")}
style={styles.img}
/>
<Image
style={{
flex: 1,
justifyContent: "center",
alignItems: "center"
}}
source={require("./img/banner02.png")}
style={styles.img}
/>
<Image
style={{
flex: 1,
justifyContent: "center",
alignItems: "center"
}}
source={require("./img/banner03.png")}
style={styles.img}
/>
</Swiper>
</View>
);
};
renderNotice = () => {
return (
<View style={styles.noticeContainer}>
<View style={styles.noticeInner}>
<NoticeBar
style={{
width: "100%",
backgroundColor: "white"
}}
mode="link"
onPress={() => alert("link")}
marqueeProps={{
loop: true,
style: { fontSize: 12, color: OAColor.lightText }
}}
// icon={
// <IconView type={'\uf604'} size={15} color={OAColor.lightText} />
// } // 开始图标自定义
action={
<TouchableOpacity
style={styles.noticeMore}
onPress={() => mb.getNavigator().push("MessageScene")}
>
<Text style={{ color: OAColor.lightText }}>更多</Text>
<IconView type={"\uf604"} size={15} color={OAColor.lightText} />
</TouchableOpacity>
}
>
通知:
app将在3月4号凌晨进行例行更新,届时系统可能出现不稳定现象,敬请谅解!
</NoticeBar>
{/* <Image
source={require('./img/home_search_nor.png')}
style={{ marginRight: 15 }}
/>
<Text numberOfLines={2} style={{ width: '70%' }}>
消息标题消息标题消息标题消息标题消息标题消息标题消息标题消息标题消息标题消息标题消息标题消息标题消息标题消息标题消息标题消息标题消息标题消息标题
</Text>
<TouchableOpacity
style={styles.noticeMore}
onPress={() => mb.getNavigator().push('MoreNavScene')}
>
<Text>更多</Text>
<Image source={require('../../assets/img/ic_next.png')} />
</TouchableOpacity> */}
</View>
</View>
);
};
renderMainNav = () => {
return (
<CustomNavIcon
style={{ marginHorizontal: OAVariables.h_spacing_lg }}
itemStyle={{ width: "25%" }}
iconStyle={{ width: OASize(50), height: OASize(50) }}
list={[
{
title: "通知公告",
icon: navArray[0],
onPress: () => {
mb.getNavigator().push("ActiveScene", { tabName: "通知公告" });
}
},
{
title: "落实整改",
icon: navArray[1],
onPress: () => {
mb.getNavigator().push("TrackUpdateScene");
}
},
{
title: "前沿",
icon: navArray[2],
onPress: () => {
mb.getNavigator().push("ActiveScene", {
tabName: "新闻中心",
tag: "前沿"
});
}
},
{
title: "规章制度",
icon: navArray[3],
onPress: () => {
mb.getNavigator().push("StudyScene");
}
}
// {
// title: '全部',
// icon: require('./img/home_visit.png'),
// onPress: () => {
// mb.getNavigator().push('MoreNavScene');
// }
// }
]}
/>
);
};
renderNews = () => {
return (
<View style={{ flex: 1 }}>
<SectionItem title="最新消息" rightBtnText="更多" onPress={() => {}} />
<ImagePlaceholder
parentRef={this}
ParagraphLength={2}
// isLoading={!this.alreadyLoad && loadStatus === LoadStatus.Loading}
isLoading={false}
list={this.renderTaskList}
/>
</View>
);
};
_onRefresh = () => {
this.setState({ refreshing: true });
// setTimeout模拟请求获取数据回调
setTimeout(() => {
this.setState({ refreshing: false });
}, 3000);
};
renderContent = () => {
const { refreshing } = this.state;
return (
<View style={{ flex: 1, marginTop: NAVBAR_HEIGHT }}>
<ScrollView
style={{ flex: 1 }}
refreshControl={
<RefreshControl
// size={RefreshControl.SIZE.LARGE} // size属性改变Android上的indicator的大小,值默认为DEFAULT,可以改成 LARGE.
enabled={true}
colors={[OAColor.headBg, "white"]} // colors属性改变Android上的indicator的颜色,值为数组,可以只设置一个颜色,
tintColor={OAColor.headBg} // tintColor属性改变iOS上的indicator的颜色,只能指定一个值。
refreshing={refreshing}
onRefresh={this._onRefresh}
/>
}
>
{this.renderSwiper()}
<View style={{ flex: 1 }}>
<Text
style={{
zIndex: 2,
position: "absolute",
top: -62,
width: "70%",
color: OAColor.white,
paddingLeft: OAVariables.h_spacing_lg
}}
numberOfLines={1}
>
app轮播图标题
</Text>
<View
style={{
position: "absolute",
top: -70,
width: "100%",
height: 30,
paddingVertical: OASize(8),
opacity: 0.5,
backgroundColor: OAColor.black
}}
/>
</View>
{this.renderMainNav()}
{this.renderNotice()}
<WhiteSpace height={10} />
{this.renderNews()}
</ScrollView>
</View>
);
};
render() {
const { loadStatus, initialized, loginError } = this.state;
const { width, height } = Dimensions.get("window");
// if (loginError) {
// return (
// <PageStatusView
// full={true}
// status="FullServerError"
// PressBtnText="立即退出"
// retryCb={() => {
// mb.quitSubProject && mb.quitSubProject();
// }}
// />
// );
// }
// if (!initialized) {
// return (
// <View style={{ ...OAStyles.center, width, height }}>
// <LoadingView size="lg" />
// </View>
// );
// }
return (
<View
style={{
flex: 1
}}
>
{this.renderContent()}
</View>
);
}
fetchData = () => {
if (this.isLoading) return;
this.isLoading = true;
this.changeLoadStatus(LoadStatus.Loading);
this.setState({
isRefreshing: true,
loadStatus: LoadStatus.Loading
});
const p1 = new Promise(resolve => {
setTimeout(() => {
resolve("ha");
}, 300);
});
const p2 = NewVisitedPlanList(1, 6);
// const p2 = VisitedPlanList({}, 1, 6);
// Promise.all([p1, p2])
// .then(([p1, res]) => {
// this.isLoading = false;
// this.alreadyLoad = true;
// this.tagCost('fetchData');
// this.setState({
// visitPlanDto: res || { total: 0 }, // default 0
// loadStatus: LoadStatus.Idle,
// isRefreshing: false
// });
// })
// .catch(e => {
// this.isLoading = false;
// this.alreadyLoad = false;
// let targetStatus = getErrorStatus(e);
// this.setState({
// isRefreshing: false,
// loadStatus: targetStatus
// });
// });
};
changeLoadStatus = status => {
this.setState({ loadStatus: status });
};
renderErrorListContent = () => {
const minHeight =
this.mScrollHeight -
(this.mShadowTop + this.mCenterTop) +
scrollRange +
15;
return (
<PageStatusView
status={this.state.loadStatus}
containerStyle={{
minHeight: minHeight,
backgroundColor: OAColor.white,
paddingBottom: OASize(60)
}}
retryCb={() => this.fetchData()}
/>
);
};
renderItem = () => {
return (
<HomeNewsItem
key={item.key}
item={item}
handleJumpPage={() => {
mb.getNavigator().push("ActiveNewsDetailScene");
}}
/>
);
};
// 渲染任务
renderTaskList = () => {
// const { data } = this.state;
const userId = "31123"; // 预留
return (
<RefreshPageContainer
style={{ marginTop: 10, backgroundColor: OAColor.barTint }}
reqFunc={getRecentNewsList}
param={[`${userId}`]}
renderItem={this.renderItem}
pager={true}
pageSize={6}
showSeparatorComponent={false}
pageStatusStyle={{ marginTop: 45 }}
/>
);
};
// 渲染空列表
_renderEmpty = () => {
return (
<PageStatusView
status={LoadStatus.Empty}
imgStyle={{
width: OASize(55),
height: OASize(55),
marginBottom: OASize(8)
}}
containerStyle={{ minHeight: OASize(120) }}
textStyle={{ fontSize: OASize(12) }}
/>
);
};
}
const styles = StyleSheet.create({
img: {
width: Dimensions.width,
height: OASize(200)
},
noticeContainer: {
paddingVertical: OAVariables.h_spacing_lg,
paddingHorizontal: OAVariables.h_spacing_lg
},
noticeInner: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
height: OASize(44),
borderRadius: OASize(5),
elevation: 20, // android 阴影 以下四项属于ios
shadowOffset: { width: 0, height: 0 },
shadowColor: OAColor.black,
shadowOpacity: 0.15,
shadowRadius: 5
},
noticeMore: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center"
// marginLeft: OAVariables.h_spacing_lg
}
});