9

アクティビティの 1 つでボトム シートを実装しようとしていますが、その動作にちょっと混乱しています!

ここに問題があります。ボトムシートを表示しようとしているアクティビティがあり、次のことがわかります。

  1. プロパティを設定しないとapp:behavior_peekHeight、Bottom シートは機能しません

  2. PeekHeight を 30dp 未満に設定した場合 (基本的には画面から非表示にするため)

  3. app:behavior_peekHeightレイアウト ファイルで 30 dp 以上に設定し、onCreate メソッドでの状態を設定しようとするとbottomSheetBehaviorSTATE_HIDDENこのエラーでアプリがクラッシュします

のせいで:

java.lang.NullPointerException: Attempt to invoke virtual method
'java.lang.Object java.lang.ref.WeakReference.get()' on a null object reference             at    android.support.design.widget.BottomSheetBehavior.setState(BottomSheetBehavior.jav    a:440)
at myapp.activity.SomeActivity.onCreate(SomeActivity.java:75)

onCreateで非表示にできないのはなぜですか?または、peekHeight を 0 に設定して、 を呼び出すSTATE_EXPANDEDか、そのプロパティを設定しない限り、画面に表示されないようにすることはできません。または、少なくとも onCreate! で非表示に設定できるはずです。

私は何かを逃していますか?または、BottomSheet の動作は厳格ですか?

BottomSheet の私のレイアウト ファイルは次のようなものです。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:background="@android:color/white"
android:layout_height="100dp"
android:orientation="vertical"
app:behavior_hideable="true"
app:behavior_peekHeight="40dp" <!-- I cant set this less than 30dp just to hide-->
app:layout_behavior="@string/bottom_sheet_behavior"
tools:context="someActivity"
android:id="@+id/addressbottomSheet"
tools:showIn="@layout/some_activity">

私の活動では、次のようなことをしています:

@InjectView(R.id.addressbottomSheet)
 View bottomSheetView;
@Override
protected void onCreate(Bundle savedInstanceState) {
....
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheetView);

// only if I have set peek_height to more than 30dp
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); 
}

私のonclickで私はこれをやっています:

@Override
public void onItemClick(View view, int position) {
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
4

4 に答える 4

5

この問題にさらに数日間取り組んだ後、これに対する別の解決策を見つけました。

Bottom_sheet をレイアウト内で直接使用する代わりに、Bottom_Sheet フラグメントを作成してからアクティビティでインスタンス化すると、この問題は発生せず、下部シートは非表示になり、peek_height を指定する必要はありません。

これが私がしたことです

public class BottomSheetDialog extends BottomSheetDialogFragment implements View.OnClickListener {
    @Override
    public View onCreateView(LayoutInflater inflater, 
                             ViewGroup container, 
                             Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_bottom_sheet, container, false);
}

それから私の活動では

bottomSheetDialog = BottomSheetDialog.newInstance(addressList.get(position), position);
bottomSheetDialog.show(getSupportFragmentManager(), AddressActivity.class.getSimpleName());

これにより、アクティビティの開始時にボトムシートが非表示にならないという問題が実際に解決されましたが、bottom_sheet が直接含まれている場合にその問題に直面する理由をまだ理解できません!

于 2016-03-21T20:53:48.677 に答える
3

(質問を参照してください)Suzzi broコードの問題は、onCreate内でsetStateメソッドを直接呼び出そうとしていることです。WeakReference がまだ初期化されていないため、これは nullPointer をスローします。Coordinator レイアウトが子ビューを配置しようとすると、初期化されます。

onLayoutChild(CoordinatorLayout 親、V 子、int layoutDirection)

親 CoordinatorLayout が指定された子ビューのレイアウトに関する場合に呼び出されます。

したがって、最適な方法は、ピークの高さを 0 に設定し、onItemClick リスナー内で表示/非表示にすることです。これが私のコードです:

ボトムシート.xml

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:gravity="center"
    android:orientation="vertical">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Bottom sheet"
        android:textColor="@android:color/black" />

</LinearLayout>

activity_main.xml

<Button
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Show hide bottom sheet" />


<include
    android:id="@+id/gmail_bottom_sheet"
    layout="@layout/bottom_sheet" />

MainActivity.java

 public class MainActivity extends AppCompatActivity {
        boolean isExpanded;
        Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        CoordinatorLayout coordinatorLayout = (CoordinatorLayout) findViewById(R.id.gmail_coordinator);
        final View bottomSheet = coordinatorLayout.findViewById(R.id.gmail_bottom_sheet);
        final BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
        button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (isExpanded) {
                    behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
                } else {
                    behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
                }
                isExpanded = !isExpanded;
            }
        });

    }
    }

ここでは、最初は一番下のシートが表示されていません。ボタンをクリックすると、状態が STATE_COLLAPSED/STATE_EXPANDED に設定されます。

このデモ アプリを作成するために従ったチュートリアルを以下に示します。 Android デザイン サポート ライブラリを使用したボトム シート

于 2016-03-26T14:55:20.827 に答える
1

クラッシュする理由は、onLayoutChild の最後の行の 1 つまで弱い参照が設定されていないためです。これにより、null ptr 例外が発生します。

できることは、カスタムの BottomSheet Behavior を作成し、onLayoutChild をオーバーライドして、そこに展開された状態を設定することです。

例はここにあります: NullPointerExeption with AppCompat BottomSheets

于 2016-03-20T18:50:30.173 に答える