Note: Read the edits at the bottom
OK, I've found a way to do it, but I had to change the code of multiple classes, so that the bottom sheet would know of the state of the appBarLayout (expanded or not), and ignore scroll-up in case it's not expanded:
BottomSheetLayout.java
Added fields:
private AppBarLayout mAppBarLayout;
private OnOffsetChangedListener mOnOffsetChangedListener;
private int mAppBarLayoutOffset;
init() - added this:
mOnOffsetChangedListener = new OnOffsetChangedListener() {
@Override
public void onOffsetChanged(final AppBarLayout appBarLayout, final int verticalOffset) {
mAppBarLayoutOffset = verticalOffset;
}
};
Added function to set the appBarLayout:
public void setAppBarLayout(final AppBarLayout appBarLayout) {
if (mAppBarLayout == appBarLayout)
return;
if (mAppBarLayout != null)
mAppBarLayout.removeOnOffsetChangedListener(mOnOffsetChangedListener);
mAppBarLayout = appBarLayout;
mAppBarLayout.addOnOffsetChangedListener(mOnOffsetChangedListener);
}
onDetachedFromWindow() - added this:
if (mAppBarLayout != null)
mAppBarLayout.removeOnOffsetChangedListener(mOnOffsetChangedListener);
onTouchEvent() - added this:
...
if (bottomSheetOwnsTouch) {
if (state == State.EXPANDED && scrollingDown && mAppBarLayout != null && mAppBarLayoutOffset != 0) {
event.offsetLocation(0, sheetTranslation - getHeight());
getSheetView().dispatchTouchEvent(event);
return true;
}
...
Those were the main changes. Now for what sets them:
MyFragment.java
onCreateView() - added this:
mBottomSheetLayout.setAppBarLayout((AppBarLayout) view.findViewById(R.id.appbar));
I also added this function:
public void setBottomSheetLayout(final BottomSheetLayout bottomSheetLayout) {
mBottomSheetLayout = bottomSheetLayout;
}
Now this is how the activity tells the fragment about the appBarLayout:
final MyFragment myFragment = new MyFragment();
myFragment.setBottomSheetLayout(bottomSheetLayout);
myFragment.show(getSupportFragmentManager(), R.id.bottomsheet);
The project is now available on GitHub:
https://github.com/AndroidDeveloperLB/ThreePhasesBottomSheet
I hope it doesn't have any bugs.
The solution has bugs, sadly, so I won't mark this answer as the correct one:
- It only works well on Android 6 and above. Others have a weird behavior of showing the bottom sheet expanded for a tiny fraction of a time, each time when showing it.
- Orientation changes do not save the state of the scrolling at all, so I've disabled it.
- Rare issue of being able to scroll inside the bottom sheet's content while it's still collapsed (at the bottom)
- If a keyboard was shown before, the bottom sheet might get to be full screen when trying to peek.
If anyone can help with it, please do.
For issue #1, I've tried adding a fix by setting the visibility to INVISIBLE when the bottom sheet doesn't peek yet, but it doesn't always work, especially if a keyboard is shown.
For issue #1, I've found how to fix it, by just wrapping (in "fragment_my.xml") the CoordinatorLayout with any view that you wish to use (I used FrameLayout), and also put a full-sized view in it (I just put "View") , as such:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--This full sized view, together with the FrameLayout above, are used to handle some weird UI issues on pre-Android-6 -->
<View
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<...CollapsingToolbarLayout
...
It probably confused the bottomSheet when I had the CoordinatorLayout being its view.
I've updated the project, but still, if there is any way to have a nicer solution, I'd like to know about it.
In recent months, Google has published its own bottomSheet class, but as I've found it has a lot of issues, so I can't even try it out.