2016-10-03 5 views
4

非常に単純なネイティブAndroid UIコンポーネントを作成しました。私の反応したネイティブプロジェクトのボタンをクリックすると、子ビューのサイズを更新します。具体的には、このボタンをクリックすると、自分のカスタムビューのresizeLayout()を呼び出すSimpleViewManagerにコマンドを送信します。React Native:カスタムUIコンポーネントのサイズを変更する

resizeLayout()が正しく呼び出されましたが、電話番号を回転させるまで、レイアウトのサイズが変更されていないことを確認できます。明らかに、デバイスの向きを変更すると、私のカスタムビューのdraw()がトリガされますが、私が暗黙のうちに呼び出すinvalidate()もそうです。

サイズ変更の代わりに背景色を変更するなど、レイアウトの変更がうまく機能します。私のカスタムコンポーネントは次のようになります

public class CustomComponent extends RelativeLayout { 
    public CustomComponent(Context context) { 
     super(context); 
     init(); 
    } 

    public CustomComponent(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     init(); 
    } 

    public CustomComponent(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
     init(); 
    } 

    private void init() { 
     inflate(getContext(), R.layout.simple_layout, this); 
    } 

    public void resizeLayout(){ 
     LinearLayout childLayout = (LinearLayout) findViewById(R.id.child_layout); 
     RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) childLayout.getLayoutParams(); 
     layoutParams.height = 50; 
     layoutParams.width= 50; 
     childLayout.setLayoutParams(layoutParams); 

     invalidate(); 
    } 
} 

とsimple_layout.xmlは次のようになります。

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/root_layout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <LinearLayout 
     android:id="@+id/child_layout" 
     android:layout_width="100dp" 
     android:layout_height="50dp" 
     android:background="#ffee11"/> 
</RelativeLayout> 

任意の助けいただければ幸いです。

答えて

8

検索の数日後に、私は最終的にthisの反応のネイティブのrepoに関する古い報告された問題に関する答えを見つけました。

この解決策は、ReactPicker.javaおよびReactToolbar.javaで使用されているものと同じです。私はCustomComponentに次のコードを入れなければなりません。その後、requestLayout()またはinvalidate()を呼び出す必要はありません。変更は、レイアウトのLayoutParamsを更新するとすぐに反映されます。

@Override 
public void requestLayout() { 
    super.requestLayout(); 

    // The spinner relies on a measure + layout pass happening after it calls requestLayout(). 
    // Without this, the widget never actually changes the selection and doesn't call the 
    // appropriate listeners. Since we override onLayout in our ViewGroups, a layout pass never 
    // happens after a call to requestLayout, so we simulate one here. 
    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()); 
    } 
}; 
+0

ありがとうございます。カスタム追加されたJavaビューの問題を解決し、階層内で更新されないようにしました。 (上記のメソッドオーバーライドを持つコンテナにカスタムビューを配置してください) – Venryx

+0

実際、私のケースではもう1つのステップがあります:上記のコンテナビュー(RelativeLayoutから継承したもの)を追加した後、 '' container.layout (0、0、幅、高さ); '' 'である。 – Venryx

+0

ReactNativeアプリのrequestLayoutはあまり役に立たないので、私たちのライブラリは幅広く役に立ちました.0、高さ:0です。賞金を追加する。 –

0

ではなく無効化の

requestLayout(); 

を実行してみてください。

この投稿にもビューのライフサイクルに関するいくつかの良い情報があります。それはあなたが何であったかでない限り

Usage of forceLayout(), requestLayout() and invalidate()

は、私はまた、

<merge> 

あなたCustomComponentクラスは、その直接の子としてRelativeLayoutを持っていません。そのように、あなたのビューのXMLにルート要素を変更することをお勧めします行く。

+0

こんにちは、ありがとうございます。実際には ''を使うのは良い考えです。しかし、私はすでにCustomComponentとchildLayoutの両方で上記のすべてのメソッドを呼び出すことを試みました。コードはAndroidプロジェクトでうまく動作します。この問題は、React Nativeと組み合わせて使用​​すると表示されます。 – George

関連する問題