版權聲明:本文爲博主原創文章,未經博主容許不得轉載。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調用時遇到的一個問題,歡迎你們支持。