4

I'm trying to implement BottomSheetBehavior from Android Support Design Library. I initialize BottomSheetBehavior like this:

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();
    }

It's very strange, because I can change state with Button click or some other action. Please, help me.

Roman Svyatnenko
  • 699
  • 12
  • 27
  • Remove this line View bottomSheetFrame = rootView.findViewById(R.id.bottom_sheet); outiside of async task, and make find the view inside onCreate method. Also if you are updating a view you should do in onPostExecute method. – AndroidRuntimeException Mar 14 '16 at 23:05
  • @AgustinSivoplás, thank you very much. I event didn't notice method is called from `doInBackground()`. – Roman Svyatnenko Mar 14 '16 at 23:20

2 Answers2

8

Problem

NPE happens because you call BottomSheetBehavior.setState(...) before your view — bottomSheetFrame was laid out. At this moment BottomSheetBehavior have null reference on the view and can't apply your state to it.

Solution

I fixed this by using View.post(Runnable) method:

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

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

In my situation this helped to stop NPE-s :)

Alexey Terekhov
  • 422
  • 4
  • 6
1

If you are using it in a Fragment, just be sure to call it on the onCreateView() method. And if you are using it on an Activity, then call it at the onCreate() method.

At those points, your Views have to be already created, unless you are creating them programmatically.

Since you are calling methods that are related with the UI from an AsyncTask, then you'll need to surround it with the runOnUiThread as explained here https://stackoverflow.com/a/27992603/973919

Basically, you need to call to anything that is related with views, from the main thread of the app, which is the UI thread.

xarlymg89
  • 2,552
  • 2
  • 27
  • 41