react-native 在android封装原生listView
react-native 在android封装原生listView前言react-native中的ListView的性能问题是react-native开发的一个痛点。虽然0.43中推出了FlatList,但是快速滑动的时候的白屏问题仍然是很影响用户体验。 问题ios轻易的完成了封装,但是android这边却遇到了坑–listView的更新实时,setAdapter或者adapter.notifyDataSetChanged后页面没有进行相应的更新,必须滚动页面后才会进行相应的刷新。 思考作为一名程序猿,首先当然是上google去了。遗憾的是没有找到任何有用的信息,甚至没有人提出这个问题。没办法,自己撸源码去。首先看了一下listView中setAdapter和adapter.notifyDataSetChanged的源码,发现其最终都是调用requestLayout来更新页面的。
解决既然requestLayout是层层向上传递,那么问题就应该是在父view上了。作为一个控件,在使用中,其父view必然是一个react-native的控件。而react-native的view大部分是继承View,所以我又查看了一下VIew的原生实现ReactVIewGroup的源码,终于找到了原因所在: @Override
public void requestLayout() {
// No-op,terminate `requestLayout` here,UIManagerModule handles laying out children and
// `layout` is called on all RN-managed views by `NativeViewHierarchyManager`
}
React-Native重写了ReactViewGroup的requestLayout方法,这使得ListView在使用requestLayout的时候无法事件无法传递到ViewRootImpl。就是说,所有的view在ReactNative都将失效。 知道问题所在,事情就好解决了。在Stack Overflow找到了解决的方法: @Override
public void requestLayout() {
super.requestLayout();
// The spinner relies on a measure + layout pass happening after it calls requestLayout().
// Without this,the widget never actually changes the selection and doesn't call the
// appropriate listeners. Since we override onLayout in our ViewGroups,a layout pass never
// happens after a call to requestLayout,so we simulate one here.
post(measureAndLayout);
}
private final Runnable measureAndLayout = new Runnable() {
@Override
public void run() {
measure(
MeasureSpec.makeMeasureSpec(getWidth(),MeasureSpec.EXACTLY),MeasureSpec.makeMeasureSpec(getHeight(),MeasureSpec.EXACTLY));
layout(getLeft(),getTop(),getRight(),getBottom());
}
};
http://stackoverflow.com/questions/39836356/react-native-resize-custom-ui-component (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |