I have an activity which has CoordinatorLayout
as a root layout. Inside that, there's a FrameLayout
layout which is hidden and programmatically has been set a fragment which is revealed from the bottom on a button click. That fragment consists of a grid RecyclerView
which is scrollable.
If you focus on the toolbar you can see behind view gets scroll down and shows the behind view image when the grid view scroll content is over.
This is the layout of my activity
Activity Layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinator_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:focusableInTouchMode="true"
tools:context=".activities.hotels.HotelDetailActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/app_bar_height"
android:fitsSystemWindows="true"
android:theme="@style/AppTheme.AppBarOverlay"
app:layout_behavior="android.support.design.widget.AppBarLayout$Behavior">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:toolbarId="@+id/toolbar"
app:expandedTitleTextAppearance="@style/TransparentText"
app:collapsedTitleTextAppearance="@style/ExpandedAppBar"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:titleEnabled="true">
<ImageView
android:id="@+id/main_hotel_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
android:src="@drawable/temp_hotel"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tool_bar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/roboto_medium"
android:text="Hotel Name"
android:singleLine="true"
android:textColor="@android:color/white"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tool_bar_sub_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Thu, 10 Jan 2019 - Sat, 12 Jan 2019"
android:textColor="@color/white"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tool_bar_title" />
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_scrolling" />
<FrameLayout
android:id="@+id/more_detail_fragment_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:visibility="gone"
android:layout_gravity="center"
android:gravity="center"
android:layout_marginTop="56dp"
android:layout_marginBottom="56dp"
android:clickable="true"/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/fab_margin"
android:src="@drawable/ic_photo_library"
app:backgroundTint="@color/white"
app:fabSize="mini"
app:layout_anchor="@id/app_bar"
app:layout_anchorGravity="bottom|end" />
<android.support.constraint.ConstraintLayout
android:id="@+id/bottom_message_container"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="@drawable/clickable_bottom_bar_background"
android:layout_gravity="bottom"
android:gravity="bottom">
<android.support.constraint.ConstraintLayout
android:id="@+id/bottom_message_container_child"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/price_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginBottom="8dp"
android:fontFamily="@font/roboto_regular"
android:text="LKR 0"
android:textColor="@android:color/white"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<TextView
android:id="@+id/detail_titel_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginStart="8dp"
android:fontFamily="@font/roboto_light"
android:text="Starting From"
android:textColor="@android:color/white"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<FrameLayout
android:id="@+id/continue_button"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginTop="8dp"
android:background="@drawable/secondary_button_background"
android:clickable="true"
android:paddingEnd="8dp"
android:paddingStart="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/button_color"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:fontFamily="@font/roboto_medium"
android:text="Continue"
android:textColor="@android:color/white"
android:textSize="16sp" />
</FrameLayout>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
</android.support.design.widget.CoordinatorLayout>
Fragment Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".fragments.hotels.AllHotelAmenitiesFragment"
android:orientation="vertical"
android:background="@color/white"
android:clickable="true">
<TextView
android:id="@+id/hotel_amenities_title_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:fontFamily="@font/roboto_medium"
android:text="Hotel Amenities"
android:textColor="@color/textColorPrimary"
android:textSize="14sp"
android:layout_marginStart="16dp" />
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="8dp"
android:background="@color/divider"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/recycler_view_expand_layout"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/main_hotel_amenities_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clickable="true"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"/>
</LinearLayout>
HotelDetailActivity
public class HotelDetailActivityEdit extends AppCompatActivity{
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.more_detail_fragment_holder)
FrameLayout allHotelAmenityHolder;
@BindView(R.id.app_bar)
AppBarLayout appBarLayout;
@BindView(R.id.recycler_view_expand_layout)
FrameLayout recyclerViewExpandLayout;
private boolean allAmenitiesFragmentIsHidden;
private Animation revealFromBottom;
private Animation unRevealFromBottom;
private AllHotelAmenitiesFragment allHotelAmenitiesFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hotel_detail);
ButterKnife.bind(this);
initialization();
onClickHotelAmenityExpandContainer();
}
private void initialization() {
revealFromBottom = AnimationUtils.loadAnimation(this, R.anim.slide_in_bottom);
unRevealFromBottom = AnimationUtils.loadAnimation(this, R.anim.slide_out_bottom);
allAmenitiesFragmentIsHidden = true;
allHotelAmenitiesFragment = new AllHotelAmenitiesFragment();
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map_fragment);
}
private void onClickHotelAmenityExpandContainer() {
recyclerViewExpandLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (allAmenitiesFragmentIsHidden) {
allHotelAmenityHolder.startAnimation(revealFromBottom);
allHotelAmenityHolder.setVisibility(View.VISIBLE);
appBarLayout.setExpanded(false);
allAmenitiesFragmentIsHidden = false;
invalidateOptionsMenu();
}
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!allAmenitiesFragmentIsHidden)
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_action_close);
else {
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_action_arrow_back);
}
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
break;
}
return true;
}
@Override
public void onBackPressed() {
if (!allAmenitiesFragmentIsHidden) {
allHotelAmenityHolder.startAnimation(unRevealFromBottom);
allHotelAmenityHolder.setVisibility(View.GONE);
appBarLayout.setExpanded(true);
allAmenitiesFragmentIsHidden = true;
invalidateOptionsMenu();
} else {
finish();
}
}
}
AllHotelAmenitiesFragment
public class AllHotelAmenitiesFragment extends Fragment {
@BindView(R.id.main_hotel_amenities_recycler_view)
RecyclerView mainHotelAmenitiesRecyclerView;
private MainHotelAmenitiesListAdapter mainHotelAmenitiesListAdapter;
public AllHotelAmenitiesFragment() {
// Required empty public constructor
}
public void setArguments(ArrayList<HotelAmenitiesImageObject> hotelAmenitiesWithImages) {
Bundle args = new Bundle();
args.putParcelableArrayList("hotel_amenities", hotelAmenitiesWithImages);
this.setArguments(args);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_all_hotel_amenities, container, false);
ButterKnife.bind(this, view);
initialization();
return view;
}
private void initialization() {
ArrayList<HotelAmenitiesImageObject> mainHotelAmenities = getArguments().getParcelableArrayList("hotel_amenities");
mainHotelAmenitiesListAdapter = new MainHotelAmenitiesListAdapter(mainHotelAmenities);
GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), 4);
GridRecyclerViewDivider gridRecyclerItemDecorator = new GridRecyclerViewDivider(4, 16, true, 0);
mainHotelAmenitiesRecyclerView.addItemDecoration(gridRecyclerItemDecorator);
mainHotelAmenitiesRecyclerView.setLayoutManager(gridLayoutManager);
mainHotelAmenitiesRecyclerView.setAdapter(mainHotelAmenitiesListAdapter);
}
}
As you can see I have set android:clickable="true"
to the root layout of the fragment which is what usually do to stop registering clicks on behind layout. It seems when it's come to scroll it does not work like that.
I don't want my activity view behind my fragment to react to the scroll when my fragment visible. Please give me a suggestion to fix this bug.
I have run a demo, this works! It is the Gif links
disable the AppBarLayout scroll event to expand or collapse
disable the recyclerview scroll event to expand or collapse AppBarLayout
you can use scroll flag to disable it too, which i have comment, but this way will expand the AppBarLayout first
You can use these two code block to get what you want.
You should modified these code for your project
when fragment visible, ViewCompat.setNestedScrollingEnabled(mRecyclerView, false)
to disable your fragment's recyclerview not your content_scrolling
layout recyclerview.
private int state = STATE_APPBAR;
private static final int STATE_APPBAR = 1;
private static final int STATE_CONTENT = 2;
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams();
params.setBehavior(new AppBarLayout.Behavior());
AppBarLayout.Behavior appBarBehavior = (AppBarLayout.Behavior) params.getBehavior();
//code block one
if (appBarBehavior != null) {
appBarBehavior.setDragCallback(new AppBarLayout.Behavior.DragCallback() {
@Override
public boolean canDrag(@NonNull AppBarLayout appBarLayout) {
return state == STATE_APPBAR;
}
});
}
//code block two
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (state == STATE_APPBAR) {
state = STATE_CONTENT;
//setAppbarLayoutScrollFlag(AppBarLayout.LayoutParams.SCROLL_FLAG_SNAP);
ViewCompat.setNestedScrollingEnabled(mRecyclerView, false);
} else {
state = STATE_APPBAR;
//setAppbarLayoutScrollFlag(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED);
ViewCompat.setNestedScrollingEnabled(mRecyclerView, true);
}
}
});
private void setAppbarLayoutScrollFlag(int flags) {
AppBarLayout.LayoutParams lp = (AppBarLayout.LayoutParams) mToolbarLayout.getLayoutParams();
lp.setScrollFlags(flags);
mToolbarLayout.setLayoutParams(lp);
}
Apply the code in your project
AllHotelAmenitiesFragment
to get recyclerviewpublic class AllHotelAmenitiesFragment extends Fragment {
@BindView(R.id.main_hotel_amenities_recycler_view)
RecyclerView mainHotelAmenitiesRecyclerView;
private MainHotelAmenitiesListAdapter mainHotelAmenitiesListAdapter;
public AllHotelAmenitiesFragment() {
// Required empty public constructor
}
public RecyclerView getRecyclerView() {
return mainHotelAmenitiesRecyclerView;
}
HotelDetailActivityEdit
add block logicprivate void onClickHotelAmenityExpandContainer() {
recyclerViewExpandLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (allAmenitiesFragmentIsHidden) {
allHotelAmenityHolder.startAnimation(revealFromBottom);
allHotelAmenityHolder.setVisibility(View.VISIBLE);
appBarLayout.setExpanded(false);
allAmenitiesFragmentIsHidden = false;
invalidateOptionsMenu();
//add block logic
RecyclerView recyclerview = allHotelAmenitiesFragment.getRecyclerView();
ViewCompat.setNestedScrollingEnabled(recyclerview, false);
}
}
});
}