使用AppCompat BottomSheets的NullPointerExeption

San*_*0rd 15 android nullpointerexception android-appcompat material-design

LinearLayout bottomSheetViewgroup = (LinearLayout) findViewById(R.id.bottomSheet);

bottomSheetBehavior = BottomSheetBehavior.from(bottomSheetViewgroup);

bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); //this line
Run Code Online (Sandbox Code Playgroud)

我在我的activity的onCreate()方法中有这个代码,当执行最后一行时,我得到了下面的NPE异常:

引发者:java.lang.NullPointerException:尝试在android.support.design.widget.BottomSheetBehavior.setState上的空对象引用上调用虚方法'java.lang.Object java.lang.ref.WeakReference.get()'( BottomSheetBehavior.java:440)

McP*_*McP 14

虽然Sanf0rds的答案是正确的,但它不允许将BottomSheet定义为默认展开.问题是由于onLayoutChild的最后一行未设置WeakReference引起的.

解决方案是提供我们自己的类,它扩展了BottomSheetBehavior,但是在重写的onLayoutChild中设置状态.代码如下.

英国/ AC/QUB/quibe /其它/ ExpandedBottomSheetBehavior.java

package uk.ac.qub.quibe.misc;

import android.content.Context;
import android.support.design.widget.CoordinatorLayout;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by mcp on 15/03/16.
 */
public class ExpandedBottomSheetBehavior<V extends View> extends android.support.design.widget.BottomSheetBehavior<V> {

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

    @Override
    public boolean onLayoutChild(final CoordinatorLayout parent, final V child, final int layoutDirection) {
        SavedState dummySavedState = new SavedState(super.onSaveInstanceState(parent, child), STATE_EXPANDED);
        super.onRestoreInstanceState(parent, child, dummySavedState);
        return super.onLayoutChild(parent, child, layoutDirection);
        /*
            Unfortunately its not good enough to just call setState(STATE_EXPANDED); after super.onLayoutChild
            The reason is that an animation plays after calling setState. This can cause some graphical issues with other layouts
            Instead we need to use setInternalState, however this is a private method.
            The trick is to utilise onRestoreInstance to call setInternalState immediately and indirectly
         */
    }

}
Run Code Online (Sandbox Code Playgroud)

在布局文件引用中引用您的新自定义行为.

更改

app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
Run Code Online (Sandbox Code Playgroud)

app:layout_behavior="uk.ac.qub.quibe.misc.ExpandedBottomSheetBehavior"
Run Code Online (Sandbox Code Playgroud)

  • 我在这个SavedState dummySavedState = new SavedState(super.onSaveInstanceState(parent,child),STATE_EXPANDED)附近添加条件; super.onRestoreInstanceState(parent,child,dummySavedState); 所以它只会发生一次 (2认同)

小智 5

public class ExpandedBottomSheetBehavior<V extends View> extends
    android.support.design.widget.BottomSheetBehavior<V> {

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

  @Override
  public boolean onLayoutChild(final CoordinatorLayout parent, final V child, final int layoutDirection) {
    return super.onLayoutChild(parent, child, layoutDirection);
  }

  @Override
  public boolean onInterceptTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
    try {
      return super.onInterceptTouchEvent(parent, child, event);
    } catch (NullPointerException ignored) {
      return false;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)