版权声明:本文为博主原创文章,未经博主容许不得转载。java
转载请代表出处:http://www.cnblogs.com/cavalier-/p/7483871.htmlreact
在现在的App中,已经有成千上万的原生UI部件了——其中的一些是平台的一部分,另外一些可能来自于一些第三方库,并且可能你本身还收藏了不少。React Native已经封装了大部分最多见的组件,譬如ScrollView
和TextInput
,但不可能封装所有组件。并且,说不定你曾经为本身之前的App还封装过一些组件,React Native确定无法包含它们。幸运的是,在React Naitve应用程序中封装和植入已有的组件很是简单。但在实施的过程当中每每会发生一些小情况,现在天分享的这个问题,当原生UI组件
动态addView时在界面中不显示。
(下面React Native 简称为RN)android
在下面代码中,咱们定义了一个原生的控件,这个组件一样也可用于RN。ide
public class RCTVideoLayout extends RelativeLayout { public RCTVideoLayout(Context context) { this(context, null); } public RCTVideoLayout(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public RCTVideoLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(context); } /** * 初始化View * * @param context */ private void initView(Context context) { View rootView = View.inflate(context, R.layout.video_layout, null); addView(rootView); } /** * 动态添加View * @param str */ public void autoAddView(String str){ Button button = new Button(getContext()); button.setText(str); addView(button); }
在这段上面的autoAddView
函数中就是一个动态添加View
的操做,若是这段代码在原生中执行是没问题的,但在RN中动态调用,会致使不管addView多少次都没问题,但在RN中每次调用均在UI中看不出有什么明显变化,经过断点也是没发现问题所在,那么到底是什么缘由致使的呢,下面我给你们分析一下。函数
发生如此诡异的状况,该怎么分析呢?Android Studio
中有个工具Layout inspector
,这个工具能够快速对手机上面的界面作分析。工具
Android Studio
打开任意工程后,按照以下图所示:
post
等待几秒后,会自动打开分析界面:ui
这个界面是一个Demo工程,里面一样也是用RN调用原生封装的组件,但一样的状况是调用了原生addView后,并无在UI上看到this
如今把全部的层级打开后,发现原生的确已经addView进去了,只不过他的height和 width 都是0,因此这样就能解释为何咱们动态添加View后看不到UI变化。
从上图中能够分析获得,不管咱们addView
多少次,所产生的View都是0高0宽
,这个明显就是没有让ViewGroup
去测量子控件。如今缘由已经明了,那么如何解决这种问题呢?那固然是让ViewGroup每次都本身测量子控件的高宽咯,咱们回到刚才的自定义ViewGroup中的代码中,添加以下代码:
//如下代码修复经过动态 addView 后看不到的问题 @Override public void requestLayout() { super.requestLayout(); 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()); } };
以上代码中所做的事情就是每次addView
后,在ViewGroup
源码中可看到addView
后,实际调用requestLayout()
函数,以下图所示:
添加代码后,咱们再次运行程序,再次经过Layout inspector
工具来看看效果:
能够发现这回终于有显示了,再看到hight和width都有对应的值了。
以上是我在封装原生控件给RN调用时遇到的一个问题,欢迎你们支持。