您的位置:首页 > Web前端 > React

React Native之无fixed属性,如何开发一个悬浮按钮

2018-03-20 17:15 489 查看
赶了一个礼拜终于开发结束,今天提测,抽空我来总结下最近遇到的棘手问题。其实真正让开发成长的是产品和测试啊。很酷炫的效果,如果实现不了,开发心里也是很难过的。。。
效果图先展示出来:



需求如下:首页默认可以展示50条新闻,新闻做成分页功能,每次请求10条新闻。当页面展示到第20条新闻的时候,才出现悬浮按钮“发现更多精彩”;一直滑动到50条,悬浮按钮一直存在。当页面向上滑动至少于20条新闻时,再将这个悬浮按钮消失。
难点:
1. 悬浮按钮如何实现。 React Native中position只有absolute和relative两个值;并没有fixed值。
2. 如何让悬浮按钮在第20条以后显示;少于20条不显示。

难点一:悬浮按钮:
新闻这一部分,用的是ScrollView。我们只需要将这个悬浮按钮写在ScrollView外部就好。大致的结构如下:return (
<View>
<ScrollView>
<View>
//新闻滚动部分
</View>
</ScrollView>
<View>
//悬浮按钮的部分
</View>
</View>
);难点二:如何定位第20条新闻
1.通过onLayout属性,可以拿到渲染成功后的页面的高度及坐标y。



2. 在新闻列表的map方法里面,通过索引index判断执行onLayout方法:
onLayout={index == 20 ? this._boxLayout.bind(this) : null}核心代码如下:'use strict';
import React, {Component} from 'react';
import {
StyleSheet,
Image,
Text,
View,
TouchableOpacity,
TouchableHighlight,
ScrollView,
NativeModules,
Platform,
AsyncStorage,
Dimensions,
ListView,
} from 'react-native';

export default class Index extends Component {
constructor(props) {
super(props);
this.state = {
listData: [],
}
this.pageHeight = 0; //
this.myY = 0; //新闻列表的第20个item距离顶部的长度(以ScrollView滑动的(0,0)点开始计算)
this.allHeight = 0; //手机屏幕的高度(除去顶部nav和底部tab栏高度)
}

onAnimationEnd(e) {
let offsetY = e.nativeEvent.contentOffset.y; //页面的高度y
}

onContentSize(contentWidth, contentHeight) {
this.pageHeight = contentHeight;
}

_boxLayout(event) {
this.myY = event.nativeEvent.layout.y;
}

_allMyLayout(event) {
this.allHeight = event.nativeEvent.layout.height;
}

scrollEvent(event) {
if (this.myY > 0 && (event.nativeEvent.contentOffset.y + this.allHeight) > this.myY) {
this.setState({
isShowFind: true
})
} else {
this.setState({
isShowFind: false
})
}
}

render() {
return (
<View onLayout={this._allMyLayout.bind(this)}>
<ScrollView
onMomentumScrollEnd={(e) => {
this.onAnimationEnd(e)
}}
onContentSizeChange={(x, y) => {
this.onContentSize(x, y)
}}
onScroll={(event) => {
this.scrollEvent(event);
}}
scrollEventThrottle={200}
>

{/* 显示新闻列表 */}
{
this.state.listData && this.state.listData.length > 0 ?
this.state.listData.map((item, index) => {
return (
<TouchableOpacity
activeOpacity={1}
onPress={() => this.gotoProductDetail(item)}
onLayout={index == 20 ? this._boxLayout.bind(this) : null}
key={index}>
{this.contentDelivery(item)}
</TouchableOpacity>
);
}) : null
}
</ScrollView>
<View style={styles.contentFindView}>
<TouchableOpacity style={styles.findMoreView} onPress={() => {
console.log(‘更多精彩’)
}}>
<View style={styles.findMore}>
</View>
</TouchableOpacity>
</View>
</View>
);
}
}

const styles = StyleSheet.create({
contentFindView: {
flex: 1,
position: "absolute",
bottom: 20,
right: "50%",
marginRight: -58
},
findMore: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
imgFind: {
resizeMode: 'contain',
width: 120,
bottom: -30,
},
iconImgStyle: {
width: 30,
resizeMode: 'contain',
},
findMoreText: {
color: Color.CM_WhiteColor
},
hotPartImage: {
width: bannerWidth,
height: bannerHeight
},
topView: {
marginTop: 4,
justifyContent: 'center',
alignItems: 'center'
},
loanQuota: {
fontSize: 45,
color: Color.CM_WhiteColor,
},
loanQuotaText: {
fontSize: 12,
color: Color.CM_QuotaTextColor,
textAlign: 'center',
marginTop: 9
},
font15: {
fontSize: 15
},
findMoreView: {
flex: 1,
alignItems: 'center',
position: 'absolute',
bottom: 0,
left: '50%',
marginLeft: -58
},
loanIndexBtn: {
width: deviceWidth * 0.86,
height: 44,
backgroundColor: Color.CM_QuotaBtnBgc,
borderRadius: 2,
justifyContent: 'center',
alignItems: 'center'
},
loanTouchBtn: {
marginTop: 20,
marginBottom: 15,
},
loanIndexBtnText: {
fontSize: 17,
color: Color.CM_WhiteColor
},
loanIconTextBox: {
flexDirection: 'row',
flexWrap: 'wrap',
backgroundColor: Color.CM_WhiteColor,
},
loanIconView: {
width: 30,
height: 30,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 15
},
bannerStyleBox: {
width: deviceWidth,
height: bannerHeight,
backgroundColor: 'transparent'
},
loanMiddle: {
backgroundColor: Color.CM_WhiteColor,
width: deviceWidth / 4,
height: 80,
justifyContent: 'center',
alignItems: 'center',
},
iconBottomText: {
color: Color.CM_FormFontColor,
fontSize: 12,
marginTop: 10,
},
4000

dotSec: {
backgroundColor: Color.CM_WhiteColor,
opacity: 0.5,
width: 4,
height: 4,
borderRadius: 3.5,
marginLeft: 2.5,
marginRight: 2.5,
zIndex: 100,
},
activeDotSec: {
backgroundColor: Color.CM_WhiteColor,
width: 15,
height: 4,
borderRadius: 3.5,
marginLeft: 2.5,
marginRight: 2.5,
},
paginationStyleSec: {
bottom: 10,
},
loanMoneyBox: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
marginTop: 10
},
loanMoneyNumber: {
color: Color.CMBlueColor,
fontSize: 30,
},
loanDayNumber: {
color: Color.CM_FormGreyColor,
fontSize: 11,
marginTop: 10,
marginBottom: 15
},
cardButton: {
marginBottom: 15,
width: deviceWidth - 30,
backgroundColor: Color.CM_WhiteColor,
borderRadius: 5,
paddingHorizontal: 15,
},
titleTextInCardButton: {
marginTop: 15,
fontSize: 12,
color: Color.CM_SixSixColor
},
rightInLoanMoneyLine: {
flexDirection: 'row',
alignItems: 'center'
},
creditButton: {
backgroundColor: Color.CM_CreditLogColor,
borderRadius: 25,
paddingHorizontal: 8,
paddingVertical: 4,
flexDirection: 'row',
alignItems: 'center',
marginRight: 10
},
imgInCreditButton: {
width: 13,
height: 13 / 52 * 60
},
textInCreditButton: {
fontSize: 10,
color: Color.CM_CreditTextColor,
marginLeft: 5
},
loanLimitUnit: {
fontSize: 13
}

});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息