计算用于动态渲染的容器高度,避免界面显示不出来
├─── 计算外盒高度
└─── 计算单个内部元素的高度、宽度
└─── 计算渲染一行,需要几个内部元素
└─── 计算当前元素总数,所需行数,以计算外盒所需高度
因为状态会被记录,所以,内存会越耗越多,处理这个的方法就是
保持被渲染部分的数据长度恒定,往回拉的时候,用下拉刷新重新请求
目前能实现这个的,就是rn 0.43之后的版本了
这个版本组件名为 FlatList
// 数组数据
let pics = [
"https://i.loli.net/2017/11/08/5a02a2733777b.jpg",
"https://i.loli.net/2017/11/08/5a02a27aa1473.jpg",
];
let jsxArr = []; // 装新生成的视图的容器
// 遍历数组,赋值到
pics.forEach((val, index)=> {
jsxArr.push(
<Text key={index}>{val}</Text>
);
});
return (
<View>
{jsxArr}
</View>
);
pics.forEach((val, index)=> {
// 避免赋值遇到双花括号,提前将数据放到临时变量中
let temp_obj = {}; // 这个不能在forEach外面单独声明,否则只能显示一条数据
let key_name = 'img_' + index;
temp_obj.uri = val;
jsxArr.push(
<Image
key={key_name}
source={temp_obj}
style={sscStyle.upload_do}
></Image>
);
});
注意代码中的 key={index} 一定要给元素加上,不然会报一个警告,是因为
列表中React需要我们为的每个元素提供一个唯一的“key”标识符,使得React能够更智能的重用一个组件(因为DOM的创建是非常耗时的),从而提高性能
react-native中key、ref、bind的作用和使用
// 基础引入
import React, { Component } from 'react';
import {
View,
ScrollView,
Image,
Text,
} from 'react-native';
// 当前页面的一些逻辑 ---- 逻辑层
import sscLogic from './logic/PayLogScreen';
export default class PayLogScreen extends Component{
constructor(p){
super(p);
this.logic = new sscLogic(this);
this.state = {
data:{
info:[], // 数据列表
page_count:1, // 数据分页属于第几页
},
loading:true, // loading层开关
};
this.logic.get_goods_list(); // 首次加载
}
// 充值记录 ---- 填充数据
log_tpl(){
let it = this;
let jsxArr = []; // 装生成新的视图的容器
// 遍历数组,赋值到
if( it.state.data.info.length!==0 ){
it.state.data.info.forEach((val, index)=> {
jsxArr.push(
it.log_list_tpl(val)
);
});
}else{
return it.no_data();
}
return jsxArr;
}
// 充值记录 ---- 模板
log_list_tpl(d){
let it = this;
return (
<View style={sscStyle.log_list_tpl} key={d.id}>
<View style={sscStyle.log_list_tpl_title_view}>
<Text style={sscStyle.log_list_tpl_title_left_text}>消费金额</Text>
<Text style={sscStyle.log_list_tpl_title_right_text}>¥{it.logic.format_money(d.total)}</Text>
</View>
<View style={sscStyle.log_list_tpl_container}>
<View style={sscStyle.log_list_tpl_container_view}>
<Text style={sscStyle.log_list_tpl_container_left_text}>支付渠道</Text>
<Text style={sscStyle.log_list_tpl_container_right_text}>{it.logic.get_pay_channel(d.channel)}</Text>
</View>
<View style={sscStyle.log_list_tpl_container_view}>
<Text style={sscStyle.log_list_tpl_container_left_text}>交易时间</Text>
<Text style={sscStyle.log_list_tpl_container_right_text}>{d.time}</Text>
</View>
</View>
{this.____separate()}
</View>
);
}
// 无数据页 ---- 视图
no_data(){
return(
<ScrollView style={sscStyle.container}>
<View style={sscStyle.no_data}>
<Image
source={require('./img/nothing.png')}
style={sscStyle.no_data_pic}
></Image>
<Text style={sscStyle.no_info}>暂时还没有支付记录哟</Text>
</View>
</ScrollView>
);
}
// loading层 ---- 视图
____loading(){
if( this.state.loading===false ){
// loading层模板,gScreen.width就是获取到的设备的宽度
return(
<View style={{width:gScreen.width}}>
<Image
source={require('./img/loading.gif')}
style={{width:45,height:15,marginTop:20,marginBottom:20,alignSelf:'center',}}
></Image>
</View>
);
}else{
return(<View style={{width:0,height:0,}}></View>)
}
}
// 渲染
render() {
if(this.state.data.page_count===0){
return this.no_data();
}else {
return (
<ScrollView
style={sscStyle.container}
onScroll={(d)=>{this.logic.if_scroll_to_bottom(d)}} // 监听滑动事件
>
{this.log_tpl()}
{this.____loading()}
</ScrollView>
);
}
}
}
import toastModule from '../third/toastModule'; // 反正是弹出临时消息用的
export default class sscLogic {
constructor(pointer){
this.p = pointer ; // 保存 视图层指针
// 分页相关
this.page_now = 1;
this.page_lock = false; // 防止重复加载
}
//++++++++++++++++++++++++++++++++++++++++++++++++++
// 基础功能
//++++++++++++++++++++++++++++++++++++++++++++++++++
// 判断是否滑动到底部
if_scroll_to_bottom(e: Object) {
let offsetY = e.nativeEvent.contentOffset.y; //滑动距离
let contentSizeHeight = e.nativeEvent.contentSize.height; //scrollView contentSize高度
let oriageScrollHeight = e.nativeEvent.layoutMeasurement.height; //scrollView高度
// contentSizeHeight 减10是为了防止底部loading层导致不能正常被拉取到
if (parseInt(offsetY + oriageScrollHeight) >= parseInt(contentSizeHeight) - 10) {
tool.log('get_goods_list');
this.get_goods_list();
}
}
//++++++++++++++++++++++++++++++++++++++++++++++++++
// 数据拉取
//++++++++++++++++++++++++++++++++++++++++++++++++++
// 拉取数据更新视图
get_goods_list() {
let get_this = this; // 保存 this指针
// 防止重复请求
if( get_this.page_lock===false){
get_this.page_lock = true;
setTimeout(()=>{
get_this.page_lock = false;
},1000);
}else{
// 退出
return;
}
tool.get_token(token=>{ // 取出token身份
let url = http.url('v1/paid/logs'), // 设置请求地址
to_page = 1,
request_url = url + '?' + 'token=' + token + '&to_page=' + get_this.page_now;
console.log("请求地址"+request_url);
let it = this.p; // 保存 视图层指针
// 开启loading层
it.setState(pre=>{
pre.loading = true;
return pre;
});
http.get(request_url, d=>{ // 拉取数据, d是回调数据
// 关闭loading层
it.setState(pre=>{
pre.loading = false;
return pre;
});
if(0===d.data.page_count){
it.setState(pre=>{
pre.data.page_count = 0;
return pre;
});
}
// 先显示新品,然后一直往后拉。当数量达到极限,则不显示了。
if( get_this.page_now > d.data.page_count){
toastModule.run('没有更多了');
return;
}
// 渲染
it.setState(pre=>{
pre.data.info = [].concat.apply(pre.data.info, d.data.info); // 追加数据
return pre;
});
get_this.page_now ++; // 增加页数
});
});
}
// 判断交易方式
get_pay_channel( type ){
switch(type){
case 0:
return '后台直充';
case 1:
return '微信';
case 2:
return '支付宝';
default:
return '未知';
}
}
/**
* 将单位分的整型,转换为元的字符串格式
* @param int money 待格式化的数
* @return string
*/
format_money(money){
let rel_money = parseInt(money);
if( isNaN(rel_money) ){
rel_money = 0;
}
let str_rmb = Math.floor(rel_money/100);
let str_dot = rel_money % 100;
// 小于10自动补零
if( str_dot<10 ) {
str_dot = "0"+str_dot +"";
}
return str_rmb + '.' + str_dot;
}
}
{
"code": 200,
"detail": "success",
"data": {
"info": [{
"total": 1,
"channel": 1,
"time": "2017-10-31 12:01:23"
}, {
"total": 1,
"channel": 1,
"time": "2017-10-31 11:47:05"
}, {
"total": 1,
"channel": 1,
"time": "2017-10-31 11:38:45"
},
"page_count": 1,
"total": 1
}
}
评论列表点此评论