Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 22108|回复: 0

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

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-4-10 09:13:57 | 显示全部楼层 |阅读模式

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

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

      ![屏幕快照 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变化。

      WechatIMG8

    解决方案

    • 从上图中可以分析得到,无论我们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工具来看看效果:

      WechatIMG9

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

    总结

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

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-4-30 03:13 , Processed in 0.078594 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表