ReactNative Android之原生UI组件动态addView不显示问题解决

版权声明:本文为博主原创文章,未经博主允许不得转载。

转载请表明出处:http://www.cnblogs.com/cavalier-/p/7483871.html

在如今的App中,已经有成千上万的原生UI部件了——其中的一些是平台的一部分,另一些可能来自于一些第三方库,而且可能你自己还收藏了很多。React Native已经封装了大部分最常见的组件,譬如ScrollViewTextInput,但不可能封装全部组件。而且,说不定你曾经为自己以前的App还封装过一些组件,React Native肯定没法包含它们。幸运的是,在React Naitve应用程序中封装和植入已有的组件非常简单。但在实施的过程中往往会发生一些小状况,如今天分享的这个问题,当原生UI组件动态addView时在界面中不显示。

(下面React Native 简称为RN)

还原场景

在下面代码中,我们定义了一个原生的控件,这个组件同样也可用于RN。

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打开任意工程后,按照如下图所示:

  • 等待几秒后,会自动打开分析界面:

    ![屏幕快照 2017-09-06 上午11.06.47](http://oupvrckn2.bkt.clouddn.com/屏幕快照 2017-09-06 上午11.06.47.png)

  • 这个界面是一个Demo工程,里面同样也是用RN调用原生封装的组件,但同样的情况是调用了原生addView后,并没有在UI上看到

  • 现在把所有的层级打开后,发现原生的确已经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()函数,如下图所示:

    ![屏幕快照 2017-09-06 上午11.21.06](http://oupvrckn2.bkt.clouddn.com/屏幕快照 2017-09-06 上午11.21.06.png)

  • 添加代码后,我们再次运行程序,再次通过Layout inspector工具来看看效果:

  • 可以发现这回终于有显示了,再看到hight和width都有对应的值了。

总结

以上是我在封装原生控件给RN调用时遇到的一个问题,欢迎大家支持。

ReactNative Android之原生UI组件动态addView不显示问题解决的更多相关文章

  1. React Native实战系列教程之自定义原生UI组件和VideoView视频播放器开发

    React Native实战系列教程之自定义原生UI组件和VideoView视频播放器开发   2016/09/23 |  React Native技术文章 |  Sky丶清|  4 条评论 |  1 ...

  2. Android开发 ---基本UI组件4:拖动事件、评分进度条、圆圈式进度条、进度条控制

    Android开发 ---基本UI组件4 1.activity_main.xml 描述: 定义了一个按钮 <?xml version="1.0" encoding=" ...

  3. Android开发 ---基本UI组件3:单选按钮、多选按钮、下拉列表、提交按钮、重置按钮、取消按钮

    Android开发 ---基本UI组件2 1.activity_main.xml 描述: 定义一个用户注册按钮 <?xml version="1.0" encoding=&q ...

  4. Android开发 ---基本UI组件2:图像按钮、单选按钮监听、多选按钮监听、开关

    Android开发 ---基本UI组件2 1.activity_main.xml 描述: 定义一个按钮 <?xml version="1.0" encoding=" ...

  5. Android经常使用UI组件 - TextView

    TextView是Android里面用的最多的UI组件,一般使用在须要显示一些信息的时候,其不能输入,仅仅能初始设定或者在程序中改动. 实例:TextViewDemo 执行效果: 代码清单: 布局文件 ...

  6. Android经常使用UI组件 - Button

    button(Button)是Android其中一个经常使用的UI组件.非常小可是在开发中最经常使用到.一般通过与监听器结合使用.从而触发一些特定事件. Button继承了TextView.它的功能就 ...

  7. Android学习笔记⑦——UI组件的学习AdapterView相关1

    AdapterView是一个非常重要的组件之一,他非常灵活,所以得好好学...AdapterView本身是一个抽象类,派生出来的子类用法也十分相似,只是界面有一定的区别,因此本节把他们归为一类 Ada ...

  8. Android学习笔记⑤——UI组件的学习TextView相关

    TextView是一个强大的视图组件,直接继承了View,同时也派生出了很多子类,TextView其作用说白了就是在布局中显示文本,有点像Swing编程中的JLabel标签,但是他比JLabel强大的 ...

  9. Android学习笔记⑧——UI组件的学习AdapterView相关2

    前面都是用ListView控件来配合Adapter做的一些实例,这次我们来见识一下GridView与Adapter之间的爱恨情仇.... GridView是用于在界面上按行.列分布的方式来显示多个的组 ...

随机推荐

  1. 【Spring系列】spring mvc整合任务调度

    一.在dispatcher-servlet.xml中增加定时任务扫描路径和其余配置信息 xmlns:task="http://www.springframework.org/schema/t ...

  2. 网络1711班 C语言第四次作业批改总结

    网络1711班 C语言第四次作业批改总结 助教有话说(写在前面) 近来,有同学跟老师和助教们反映:博客作业太多太麻烦,而且对编程能力提高似乎没什么帮助?在这里我要谈一谈我的感想. 博客作业的意义? 首 ...

  3. Beta冲刺NO.1

    Beta冲刺 第一天 1. 昨天的困难 由于今天还是第一天,所以暂时没有昨天的困难. 2. 今天解决的进度 潘伟靖: 对代码进行了review 1.将某些硬编码改为软编码 2.合并了一些方法,简化代码 ...

  4. 团队开发---”我爱淘“校园二手书店 NABC分析

    本项目特点之一:可预订 N:对于一些抢手的书可以提前预定,避免学生买不到书 A:网上下单,通过手机便捷购物 B:使得订书更加方便快捷 C:二手书摊.网上书店 团队成员:杨广鑫.郭健豪.李明.郑涛

  5. 2017-2018-1 1623 bug终结者 冲刺003

    bug终结者 冲刺003 by 王旌含 今日任务:优化界面布局,提供图片素材 需求 app图标.主界面图.主界面中按钮图:选择关卡图.关卡按键图:游戏中的小人.箱子.地板.墙.目的地:方向按钮:重置按 ...

  6. 2018C程序设计—第0次作业

    1.翻阅邹欣老师博客关于师生关系博客,并回答下列问题,每个问题的答案不少于500字 1)最理想的师生关系是健身教练和学员的关系,在这种师生关系中你期望获得来自老师的哪些帮助? 答:正如邹欣老师博客里所 ...

  7. MySQL的小Tips

    交集和差集 MySQL中没有这两个运算,但是有并集运算,所以可以利用这个来间接实现. 差集: SELECT ID FROM ( SELECT DISTINCT A.AID AS ID FROM TAB ...

  8. win7 Anaconda 安装 scrapy模块

    之前用了很多方法,都安装不成功,今天终于成功了..说下方法.. anaconda的清华镜像:https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ ...

  9. OpenGL中怎么把世界坐标系变成屏幕坐标系

    对这个3D坐标手动进行OpenGL的四个变换,得到的结果就是屏幕上的像素坐标.前三个变换(Model, View, Projection)都是4x4矩阵,操作对象是四维向量,所以需要把(100, 10 ...

  10. 第一章 jQuery基础

    第一章jQuery基础 一.jQuert简介 1.什么是jQuery jQuery是javaScript的程序库之一,它是javaScript对象和实用函数的封装. jQuery是继Prototype ...