尝试了解Android支持库23.2.1中

时间:2016-03-20 05:54:05

标签: android android-support-library bottom-sheet

我正在尝试在我的一项活动中实施Bottom表格,我对它的行为方式感到困惑!

所以这就是问题,我有一个活动,我试图显示Bottom表,我看到了:

  1. 如果我们不设置app:behavior_peekHeight属性,则底部工作表永远无效

  2. 如果你将PeekHeight设置为小于30dp的东西(基本上只是为了将其隐藏在屏幕之外)

  3. 如果您在布局文件中将app:behavior_peekHeight设置为超过30dp,并尝试在您的onCreate方法中将bottomSheetBehavior的状态设置为STATE_HIDDEN,则您的应用会因此错误而崩溃
  4. 引起:

    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 个答案:

答案 0 :(得分:4)

在这个问题上工作了几天之后,我找到了一个替代解决方案:

不是直接在布局中使用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我们就会遇到这个问题!

答案 1 :(得分:1)

它崩溃的原因是因为在onLayoutChild的最后一行之前没有设置弱引用,这会给你的null ptr异常。

您可以做的是创建自定义BottomSheet行为并覆盖onLayoutChild,在那里设置展开状态。

可以在这里找到一个例子: NullPointerExeption with AppCompat BottomSheets

答案 2 :(得分:1)

(参考问题)Suzzi与你的代码有关的问题是你试图直接在onCreate中调用setState方法。这将抛出一个nullPointer,因为WeakReference尚未初始化。当协调器布局即将放置其子视图时,它将被初始化。

  

onLayoutChild(CoordinatorLayout parent,V child,int layoutDirection)

     

当父级CoordinatorLayout关于布局时调用   给予孩子观点。

因此,最佳方法是将peek height设置为0并在onItemClick侦听器中显示/隐藏。 这是我的代码:

bottom_sheet.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。

我制作这个演示应用程序的教程如下: Bottom Sheet with Android Design Support Library

答案 3 :(得分:1)

要避免Null指针异常,请在onCreate()中将状态设置为HIDDEN

View bottomSheetView = findViewById(R.id.bottomsheet_review_detail_id);
mBottomSheetBehavior = BottomSheetBehavior.from(bottomSheetView);
bottomSheetView.post(new Runnable() {
            @Override
            public void run() {
                mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
            }
        });