摘要: 很多平台提供的低代码平台,其实都是通过一个设计器设计后生成的DSL配合一个运行时来生成最终产品的方案。 比如要做一个页面,放置一个按钮,在点击按钮后需要请求一个接口然后根据请求结果来判断弹出一个弹窗还是展示Toast,那么一般的低代码工具所给出的简单方案都不足以满足条件,因为他们只提供了简单执行单元 阅读全文
posted @ 2022-08-30 01:09 RockyF 阅读(465) 评论(0) 推荐(0) 编辑
摘要: 笔者作为一个arm小白,从零开始学习arm开发! 阅读全文
posted @ 2019-10-17 16:12 RockyF 阅读(9795) 评论(0) 推荐(2) 编辑
摘要: 再度分析Egret的种种种种 阅读全文
posted @ 2016-10-15 20:56 RockyF 阅读(1521) 评论(3) 推荐(0) 编辑

今天来写一个组件,相信很多人都会用到的——ViewStack。

ViewStack组件无疑是UI中很重要的一个组件,可惜react-native并没有内嵌进去,需要开发者自己去实现。

实现原理很简单,就是根据索引来显示一个子视图,用一个render即可完成:

1 render(){
2     return(
3         <View>
4             {this.props.children[this.props.index]}
5         </View>
6     );
7 }

这样,一个最简单的ViewStack就完成了,那怎么使用呢:

1 <ViewStack index={this.state.tabIndex}>
2     <PageSNS/>
3     <PageGroup/>
4     <PageLibrary/>
5     <PageChat/>
6     <PageProfile/>
7 </ViewStack>

通过修改state的tabIndex来切换子视图即可。

是不是挺简单呢!但是,你用着用着就会发现,这有点问题,当你来回切换视图的时候,会发现,子视图的状态每次都重置了,比如在PageSNS视图上,你滚动列表到了下面,然后切换到了其他子视图,再切换回来,会发现列表又从回到顶部了。

那么问题来了,有些开发者就想要这样的体验,那没事。而有些需求确是必须要保留状态,那怎么整呢?

为什么子视图会被重置呢?那就要涉及到react的渲染机制了,它会再render的时候遍历一次所有子节点,把要卸载的都卸载掉,要装载的给装载上去,那就一目了然了。我们的简单版ViewStack仅仅是每次渲染一个子视图,而其他的时候会被卸载掉,当要重新渲染那个视图的时候,那个视图其实已经不在了,在只是新new出来(或者从对象池里拿出来并初始化后)的那个视图了,所以这就是问题的所在了。

那么怎么保留子视图的状态呢?(这个状态并不是react的state机制,而说得是整个视图的逻辑状态,好吧,我也扯不清楚了)

我做了一些测试,发现只要组件被卸载了,那么这个组件就不可能恢复了,或者说恢复代价有点高。当然,方法是有的,而且很简单,只是这种方法比较鲁莽,听我道来。

在使用Navigator组件的时候,会发现,他的子视图怎么能保留状态呢,这个很神奇,难道他把什么引用存起来了?然后我深入Navigator的源码看了下去,发现他坑爹把全部子视图都render了,把要显示的视图给显示,而不需要显示的则移到了屏幕外面,就这么简单啦,我也懵了,原来就是这种方法,相信你也会说一句靠之类的感叹词吧,但是它的确就是这么做的,所以我说这种方法有些鲁莽。

然后我就写下了2.0版的ViewStack:

 1 /**
 2  * Created by rockyl on 15/11/08.
 3  */
 4 var React = require('react-native');
 5 var {
 6     StyleSheet,
 7     Component,
 8     View,
 9     } = React;
10 var Dimensions = require('Dimensions');
11 var SCREEN_WIDTH = Dimensions.get('window').width;
12 var SCREEN_HEIGHT = Dimensions.get('window').height;
13 
14 class ViewStack extends Component {
15     constructor(props) {
16         super(props);
17     }
18 
19     static get defaultProps(){
20         return {
21             index: 0,
22         }
23     };
24 
25     render(){
26         this.views = this.props.children.map((page, i)=>{
27             var style = this.props.index == i ? [styles.viewBase] : [styles.viewBase, styles.viewDisabled];
28             return (
29                 <View
30                     key={'view_' + i}
31                     style={style}>
32                     {page}
33                 </View>
34             );
35         });
36         return (
37             <View style={[styles.container, this.props.style,]}>
38                 {this.views}
39             </View>
40         );
41     }
42 }
43 
44 var styles = StyleSheet.create({
45     container: {
46         flex: 1,
47         overflow: 'hidden',
48     },
49     viewBase: {
50         position: 'absolute',
51         overflow: 'hidden',
52         left: 0,
53         right: 0,
54         bottom: 0,
55         top: 0,
56     },
57     viewDisabled: {
58         top: SCREEN_HEIGHT,
59         bottom: -SCREEN_HEIGHT,
60     },
61 });
62 
63 module.exports = ViewStack;

so easy!

用法和简单版是一样的。

再然后,你用着用着就会发现,这切换的时候好生硬啊,秒切,略缺少点什么用户体验,比如说滚动之类的动画也要啊。

2.1版将携带动画参数和其他高级功能参数,那就要等这篇博文更新啦!

posted @ 2015-11-08 23:29 RockyF 阅读(2515) 评论(0) 推荐(1) 编辑
摘要: react-native的简单尝试 阅读全文
posted @ 2015-10-24 16:44 RockyF 阅读(408) 评论(0) 推荐(0) 编辑
摘要: Unity2D屏幕适配方案 阅读全文
posted @ 2015-09-30 10:14 RockyF 阅读(1027) 评论(0) 推荐(0) 编辑
摘要: Admob banner在第一次虽然加载成功了,但是却不显示。然后等待60秒刷新自动刷新,banner就能正常显示。如果你没遇到过这种情况,那可能你用的不是集成在play-services里的库,因为这个问题对于独立版的Admob库没问题。查了半天,才在OverStack上找到解决方案:只要在ban... 阅读全文
posted @ 2015-09-22 17:00 RockyF 阅读(1965) 评论(1) 推荐(1) 编辑
摘要: 站在自己的角度阐述了egret目前的一些局限性 阅读全文
posted @ 2015-09-06 17:36 RockyF 阅读(3137) 评论(5) 推荐(1) 编辑
摘要: 各种缓动的曲线图,存着方便日后查看! 阅读全文
posted @ 2015-07-24 10:29 RockyF 阅读(1421) 评论(0) 推荐(0) 编辑
摘要: 最近想试试语音识别,然后看到了DTW这个算法主要参考:http://www.cnblogs.com/rockyf/articles/4519352.html 1 function dtw(arr1, arr2){ 2 var matrix = []; 3 arr1.forEach(f... 阅读全文
posted @ 2015-05-21 13:06 RockyF 阅读(700) 评论(1) 推荐(0) 编辑
点击右上角即可分享
微信分享提示