Android BottomSheetBehavior setState() NullPointerException

Android BottomSheetBehavior setState() NullPointerException

我正在尝试从 Android 支持设计库实施 BottomSheetBehavior。我这样初始化 BottomSheetBehavior

private void initBottomSheet() {
        new AsyncTask<Void, Void, Void>() {

            View bottomSheetFrame = rootView.findViewById(R.id.bottom_sheet);

            }

            @Override
            protected Void doInBackground(Void... params) {
                bottomSheetBehavior = BottomSheetBehavior.from(bottomSheetFrame);

                bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
                    private boolean isOnTop = false;

                    @Override
                    public void onStateChanged(@NonNull View bottomSheet, int newState) {
                        switch (newState) {

                            case BottomSheetBehavior.STATE_DRAGGING: {
                                ...
                            }

                            case BottomSheetBehavior.STATE_SETTLING: {
                                ...
                            }

                            case BottomSheetBehavior.STATE_EXPANDED: {
                               ...
                            }

                            case BottomSheetBehavior.STATE_COLLAPSED: {
                                ...
                            }

                            case BottomSheetBehavior.STATE_HIDDEN: {
                                ...
                            }

                            default: {
                                break;
                            }
                        }
                    }

                    @Override
                    public void onSlide(@NonNull View bottomSheet, float slideOffset) {
                        ...
                });

                bottomSheetBehavior.setPeekHeight((int) Utils.convertDpToPixel(100f, activityContext));
                    bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); // NPE here

                return null;
            }

            @Override
            protected void onPostExecute(Void aVoid) {
                super.onPostExecute(aVoid);
            }
        }.execute();
    }

这很奇怪,因为我可以通过 Button 单击或其他一些操作来更改状态。请帮帮我。

问题

NPE 发生是因为您在视图 bottomSheetFrame 布局之前调用了 BottomSheetBehavior.setState(...)。此时 BottomSheetBehavior 对视图有 null 引用,无法将您的状态应用到它。

解决方案

我使用 View.post(Runnable) 方法解决了这个问题:

View sheetView = ... ;    
BottomSheetBehavior behavior = BottomSheetBehavior.from(sheetView);
int initState = BottomSheetBehavior.STATE_EXPANDED;

sheetView.post(new Runnable() {
    @Override
    public void run() {
        behavior.setState(initState);
    }
});

在我的情况下,这有助于阻止 NPE-s :)

如果您在 Fragment 中使用它,请确保在 onCreateView() 方法中调用它。如果您在 Activity 上使用它,则在 onCreate() 方法中调用它。

此时,您的视图必须已经创建,除非您以编程方式创建它们。

由于您正在从 AsyncTask 调用与 UI 相关的方法,因此您需要用 runOnUiThread 将其包围起来,如此处所述

基本上,您需要从应用程序的主线程(即 UI 线程)调用与视图相关的任何内容。