本文介绍了ReactNative封装View遇到的问题及解决方案,包括执行addView页面不刷新问题等。
本文首发:http://yuweiguocn.github.io/
《望天门山》
天门中断楚江开,碧水东流至此回。
两岸青山相对出,孤帆一片日边来。
—唐,李白
前言
在版本开发过程中,有一个需求需要将某一页面整体封装为一个View供RecatNative使用。封装完测试遇到一些问题,包括执行addView后页面没刷新;使用代码动态执行Visiable无效;使用ViewPager只绘制初始化的page,后面的page没有被绘制;RecyclerView执行notiy无效等。
解决方案
查看⻚⾯布局层级会发现React Native会使用ReactRootView作为⻚⾯布局的根布局。
![](https://img.haomeiwen.com/i618971/0a31e05cbf1227b2.png)
图 页面View层级
查看ReactRootView源码会发现onLayout方法被重写了:
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
// No-op since UIManagerModule handles actually laying out children.
}
我们知道ViewGroup的onLayout用于摆放子View,由于ReactRootView的onLayout方法被重写为空所以才导致我们封装View遇到的各种问题的出现。当View的布局被修改会调用requestLayout方法,我们可以在requestLayout方法手动执行测量及layout操作来解决此问题。
@Override
public void requestLayout() {
super.requestLayout();
reLayout();
}
public void reLayout() {
if (getWidth() > 0 && getHeight() > 0) {
int w = MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY);
int h = MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY);
measure(w, h);
layout(getPaddingLeft() + getLeft(), getPaddingTop() + getTop(), getWidth() + getPaddingLeft() + getLeft(), getHeight() + getPaddingTop() + getTop());
}
}
还有一个问题就是textView.getViewTreeObserver().addOnGlobalLayoutListener监听在RN中无效,可使用textView.getViewTreeObserver().addOnPreDrawListener替换解决该问题。
网友评论