2016-03-25 12 views
8

私はこのようなAndroidのサポートライブラリからのボトムシートを使用しています:AndroidサポートBottomSheetBehaviorは動的ではありませんか?

XML:

<LinearLayout 
    android:id="@+id/bottomSheetLinearLayout" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:background="@color/fourth_white" 
    android:orientation="vertical" 
    app:layout_behavior="android.support.design.widget.BottomSheetBehavior" /> 

私はのLinearLayoutに子ビューを追加します。

bottomSheet.addView(actionButtonView); 

を私は子ビューの追加が完了した後、私はBottomSheetBehaviorを初期化し、それを展開します。

BottomSheetBehavior sheetBehavior = BottomSheetBehavior.from(bottomSheet); 
sheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); 

これを動作しません。何も表示されません。 LinearLayoutの高さをXML内にプリセットしても、すべて白です。

LinearLayout内のすべての子ビューをXMLで追加すると、すべて正常に動作します。プログラマチックにビューを動的に追加しようとすると機能しません。

誰でも同様の問題がありましたか?

+0

理解を深めるためのコードを表示... – Vickyexpert

+1

完全なコードを投稿できますか?BottomSheetにどのようにビューを追加しますか?私はちょうど再現しようとしているので、その問題はありませんでした。 – rom4ek

+0

下部シートを追加する外部ビューグループのコードを投稿できますか?可能であれば、この動作を再現するための完全な分離コードを投稿してください。 @ rom4ekが言ったように、私も上記の問題を再現できません。 –

答えて

1

トラブルは、サイズの計算を展開しています。 BottomSheetBehaviorは、onLayoutChildメソッドで拡大されたサイズを計算します。しかし、シートレイアウトの内容を変更すると、プロセスが非同期で起動します。 RequestLayoutなどを呼び出してもだから、呼び出しの結果はこのようなものです:

  1. BottomSheetBehaviorあなたはBottomSheetにコンテンツを追加(あなたのケースで、私はそれがゼロだと思う)
  2. 古い拡張サイズを有しています。拡大されたサイズはまだ古いです。
  3. SetStateをEXPANDEDに呼び出します。 BottomSheetBehaviorは以前の拡張サイズを覚えていて、そのサイズのアニメーションを起動します。状態がSTATE_SETTLINGに変更されました!
  4. onLayoutChildが呼び出され、BottomSheetBehaviorが新しい拡張サイズを計算します。しかし、アニメーションはすでに進行中で、状態はSTATE_SETTLINGなので、BottomSheetBehaviorはサイズを変更しません。
  5. アニメーションが終了しました。ボトムシートのサイズが古いです。状態はEXPANDEDに変更されましたが、BottomSheetBehaviorはアニメーション中に拡大されたサイズが変更されたことを忘れていました。

必ずBottomSheetBehaviour実装のバグです。私のプロジェクトで

私は、このような回避策が見つかりました:

private void showPanel(final View panelContent) { 
    if (panelBehavior.getState()!=BottomSheetBehavior.STATE_EXPANDED) { 
     panelBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { 
      @Override 
      public void onStateChanged(final View bottomSheet, int newState) { 
       if (newState==BottomSheetBehavior.STATE_EXPANDED) { 
        panelBehavior.setBottomSheetCallback(null); 
        contentView.removeAllViews(); 
        contentView.addView(panelContent); 
        panelView.setVisibility(View.VISIBLE); 

       } 
      } 

      @Override 
      public void onSlide(View bottomSheet, float slideOffset) { 

      } 
     }); 
     panelBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); 
     return; 
    } 
    contentView.removeAllViews(); 
    contentView.addView(panelContent); 
    panelView.setVisibility(View.VISIBLE); 
} 

private void hidePanel() { 
    panelBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); 
    panelView.setVisibility(View.GONE); 
    contentView.removeAllViews(); 
} 

ですから、新しいコンテンツのコールShowPanelでBottomSheet示す必要があるとき。 BottomSheetをhidePanelで完全に非表示にする必要がある場合(プロジェクトで非表示にする必要がある場合)、そうでない場合はメソッドからsetVisibilityを削除できます。

回避策の考え方は、BottomSheetBehaviorが展開状態でないときにBottomSheetの内容を変更しないことです。状態が展開されていない場合は、アニメーションが終了するまで待ってから内容を変更してください。

1

は、ビューのメッセージキューに実行可能な投稿してください:

bottomSheet.post(new Runnable() { 
    @Override 
    public void run() { 
     bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); 
    } 
}); 

またはretrolambdaと:それの実装に関連BottomSheetBehavior上の動的コンテンツを含む

bottomSheet.post(() -> bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED)); 
関連する問題