Don't Collapse Toolbar When Recyclerview Fits the Screen

Don't collapse Toolbar when RecyclerView fits the screen

Final Solution (thanks Michał Z.)

Methods to turn off/on Toolbar scrolling:

public void turnOffToolbarScrolling() {
Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.appbar_layout);

//turn off scrolling
AppBarLayout.LayoutParams toolbarLayoutParams = (AppBarLayout.LayoutParams) mToolbar.getLayoutParams();
toolbarLayoutParams.setScrollFlags(0);
mToolbar.setLayoutParams(toolbarLayoutParams);

CoordinatorLayout.LayoutParams appBarLayoutParams = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
appBarLayoutParams.setBehavior(null);
appBarLayout.setLayoutParams(appBarLayoutParams);
}

public void turnOnToolbarScrolling() {
Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.appbar_layout);

//turn on scrolling
AppBarLayout.LayoutParams toolbarLayoutParams = (AppBarLayout.LayoutParams) mToolbar.getLayoutParams();
toolbarLayoutParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS);
mToolbar.setLayoutParams(toolbarLayoutParams);

CoordinatorLayout.LayoutParams appBarLayoutParams = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
appBarLayoutParams.setBehavior(new AppBarLayout.Behavior());
appBarLayout.setLayoutParams(appBarLayoutParams);
}


Find out if last item of RecyclerView is visible in my Fragment.

If yes, disable scrolling:

public void updateToolbarBehaviour(){
if (mLayoutManager.findLastCompletelyVisibleItemPosition() == items.size()-1) {
((MainActivity) getActivity()).turnOffToolbarScrolling();
} else {
((MainActivity)getActivity()).turnOnToolbarScrolling();
}
}

Block Toolbar from collapsing when RecyclerView is empty

I managed to solve this proplem in such way. First of all I blocked AppBarLayout from scrolling like explained here.
And then I placed FAB directly to the CoordinatorLayout and lincked it's hidding to the ViewPager scrolls like here.
Also I wanted an EditText floating over the one of the fragments, which are inside ViewPager. I placed it inside CoordinatorLayout and made it sliding up and down, when ViewPager scrolls.

CollapsingToolbarLayout causes RecyclerView's bottom to be underscreen

I ended up using the followiing, to detect last item scroll and notifyDataSetChanged(), that solves the issue :

    recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

private boolean hasFixedLastItemNotVisible = false;

@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);

if (!hasFixedLastItemNotVisible &&
!recyclerView.canScrollVertically(10) &&
newState==RecyclerView.SCROLL_STATE_IDLE) {
hasFixedLastItemNotVisible = true;
recyclerView.getAdapter().notifyDataSetChanged();
}
}
});

Toolbar not collapsing with nested RecyclerView

I only needed to set recyclerView.setNestedScrollingEnabled(false) for the nested RecyclerView to work.

Thanks to Reddit user in this thread:
Toolbar not collapsing with nested RecyclerView

Prevent toolbar from hiding when recyclerview has one item

Probably you need to prevent the RecyclerView from dispatching scrolling events to its parents.

     private class NoScrollTouchListener implements RecyclerView.OnTouchListener{
private static final int MAX_CLICK_DURATION = 200;
private long mStartClickTime;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
mStartClickTime = SystemClock.currentThreadTimeMillis();
break;
}
case MotionEvent.ACTION_UP: {
long clickDuration = SystemClock.currentThreadTimeMillis() - mStartClickTime;
if(clickDuration <= MAX_CLICK_DURATION) {
return false;
}
}
}
if(v instanceof RecyclerView){
boolean isLastVisible = ((LinearLayoutManager)((RecyclerView) v).getLayoutManager()).findLastCompletelyVisibleItemPosition() == ((RecyclerView) v).getAdapter().getItemCount() - 1);

boolean isFirstVisible = ((LinearLayoutManager)((RecyclerView) v).getLayoutManager()).findFirstCompletelyVisibleItemPosition() == 0);
return isLastVisible && isFirstVisible;
}
return true;
}
}

This might not be right approach but it has the concise condition when the RecyclerView does not need to scroll.

((LinearLayoutManager)mRecyclerView.getLayoutManager()).findLastCompletelyVisibleItemPosition() == mRecyclerView.getAdapter().getItemCount() - 1);

See also requestDisallowInterceptTouchEvent(disallow) of RecyclerView parent (i.e CoordinatorLayout)

Another way to try to prevent any scrolling behavior is to register data observer to your RecyclerView.Adapter and using the condition above to toggle the layout_scrollFlags of your Toolbar:

     boolean isLastVisible = ((LinearLayoutManager)((RecyclerView) v).getLayoutManager()).findLastCompletelyVisibleItemPosition() == ((RecyclerView) v).getAdapter().getItemCount() - 1);

boolean isFirstVisible = ((LinearLayoutManager)((RecyclerView) v).getLayoutManager()).findFirstCompletelyVisibleItemPosition() == 0);

if(isFirstVisible && isLastVisible){
mOldScrollFlags = mOldScrollFlags == -1 ? params.getScrollFlags() : mOldScrolFlags;
params.setScrollFlags(0);
}else{
params.setScrollFlags(mOldScrollFlags);
}
mToolbar.setLayoutParams(params);

When you set scrolling flags to 0, the AppBarLayout will exclude that view from calculating it in the total flexible range.

How to disable CollapsingToolbar's collapse when scroll has not content?

get your appbarlayout reference and set the setScrollFlags.

AppBarLayout.LayoutParams p = (AppBarLayout.LayoutParams) toolbar.getLayoutParams();
p.setScrollFlags(0);
toolbar.setLayoutParams(p);


Related Topics



Leave a reply



Submit