Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting when AppBarLayout/CollapsingToolbarLayout is completely expanded

I have a fragment that uses the new CoordinatorLayout/AppBarLayout/CollapsingToolbarLayout paradigm, and I'd like to be able to detect when the collapsing toolbar is fully expanded so that I can perform an operation on the entire fragment it's in, e.g. popping the fragment off the stack and going to a new one, dismissing the fragment. I have the dismissing code working, I just need to know when and when not to use it.

I've experimented a bit with AppBarLayout.OnOffsetChangedListener, but didn't have much luck. Is there a way to use it to determine when things are completely expanded, or is there a more preferred method someone knows about?

Thanks in advance!

EDIT: I also see there are a couple implementations for AppBarLayout.setExpanded(...), however not AppBarLayout.getExpanded() or something similar, so I'm stumped there too.

like image 897
James Pizzurro Avatar asked Aug 25 '15 20:08

James Pizzurro


People also ask

What is Collapsing Toolbar layout?

CollapsingToolbarLayout is a wrapper for Toolbar which implements a collapsing app bar. It is designed to be used as a direct child of a AppBarLayout .

How do you collapse a CollapsingToolbarLayout?

Use mAppBarLayout. setExpanded(true) to expand Toolbar and use mAppBarLayout. setExpanded(false) to collapse Toolbar.

What is the use of AppBarLayout in Android?

AppBarLayout is a vertical LinearLayout which implements many of the features of material designs app bar concept, namely scrolling gestures. Children should provide their desired scrolling behavior through AppBarLayout.


2 Answers

It doesn't look like there's anything in the APIs, but the following seems to be working for me. It might need testing.

boolean fullyExpanded =     (appBarLayout.getHeight() - appBarLayout.getBottom()) == 0; 

Edit: The above solution does seem to work, but since I wanted to test this condition when the appbar was scrolled, I ended up using the following solution with OnOffsetChangedListener.

class Frag extends Fragment implements AppBarLayout.OnOffsetChangedListener {      private boolean appBarIsExpanded = true;     private AppBarLayout appBarLayout;      @Override      public void onActivityCreated(Bundle state) {         super.onActivityCreated(state);         appBarLayout = (AppBarLayout) getActivity().findViewById(R.id.app_bar);     }      @Override     public void onResume() {         super.onResume();         appBarLayout.addOnOffsetChangedListener(this);     }      @Override     public void onStop() {         super.onStop();         appBarLayout.removeOnOffsetChangedListener(this);     }      @Override     public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {         appBarIsExpanded = (verticalOffset == 0);     }   } 
like image 149
Jimeux Avatar answered Sep 26 '22 22:09

Jimeux


My solution is based on creating a custom view. First create a class extending the native AppBarLayout:

public class CustomAppBar extends AppBarLayout { ....

Then inside the class set an addOnOffsetChangedListener like this:

this.addOnOffsetChangedListener...

You can do the above by setting in the constructor or maybe by calling a method inside the constructor. So you need the constructor, remember to use the constructor with 2 params to be able to added to the xml:

public CustomAppBar(Context context, AttributeSet attrs) {
        super(context, attrs);
//You can set the listener here or maybe call the method that set the listener
}

Then we have to get access to the state of the view, so create a private boolean inside your custom view class, and set it to true or false if your view start expanded or collapsed, in this case my view is by default expanded:

private boolean isExpanded = true;

Now you have to update the state of that boolean:

this.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                if (verticalOffset == 0) {
                    isExpanded = true;
                } else {
                    isExpanded = false;
                }
            }
        });

Next step is to get the state of the boolean by using a getter inside the CustomAppBar class

public boolean isExpanded() {
        return isExpanded;
    }

The next is go to your xml, use your custom view there, then in the Acivity or Fragment get the view and use the method to know the AppBar status

like image 32
cutiko Avatar answered Sep 26 '22 22:09

cutiko