I'm trying to do something really simple.
I would like the FAB to only appear on one tab in my TabLayout and be hidden when navigating to another tab. So for example, one tab would let you add new items in the FAB, but the next tab would not let you add items.
I have followed the 'typical' XML design layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container"
xmlns:tools="http://schemas.android.com/tools"
>
<android.support.design.widget.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways">
<LinearLayout
android:id="@+id/search_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal">
<EditText
android:id="@+id/search_view"
android:layout_width="0dp"
android:layout_height="?attr/actionBarSize"
android:layout_weight="1"
android:background="@android:color/transparent"
android:gravity="center_vertical"
android:hint="Search"
android:imeOptions="actionSearch"
android:inputType="text"
android:maxLines="1"
android:paddingLeft="2dp"
android:singleLine="true"
android:textColor="#ffffff"
android:textColorHint="#b3ffffff" />
<ImageView
android:id="@+id/search_clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:src="@drawable/ic_action_cancel" />
</LinearLayout>
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="@+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:tabMode="scrollable"
/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.example.simon.behaviours.PatchedScrollingViewBehavior"/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
app:borderWidth="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_action_new"
android:layout_margin="16dp"
android:layout_gravity="bottom|right"
app:layout_anchor="@+id/viewPager"
app:layout_anchorGravity="bottom|right|end"
app:layout_behavior="com.example.simon.behaviours.ScrollingFABBehavior"
android:visibility="gone"
app:fabSize="normal">
</android.support.design.widget.FloatingActionButton>
</android.support.design.widget.CoordinatorLayout>
I have used the following behavior for the FAB. This results in any upscrolls to cause the FAB to disappear and will return back on screen on a downscroll:
public class ScrollingFABBehavior extends FloatingActionButton.Behavior {
private int toolbarHeight;
public ScrollingFABBehavior(Context context, AttributeSet attrs) {
super();
this.toolbarHeight = getToolbarHeight(context);
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton fab, View dependency) {
return super.layoutDependsOn(parent, fab, dependency) || (dependency instanceof AppBarLayout);
}
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton fab, View dependency) {
boolean returnValue = super.onDependentViewChanged(parent, fab, dependency);
if (dependency instanceof AppBarLayout) {
CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
int fabBottomMargin = lp.bottomMargin;
int distanceToScroll = fab.getHeight() + fabBottomMargin;
float ratio = (float)dependency.getY()/(float)toolbarHeight;
fab.setTranslationY(-distanceToScroll * ratio);
}
return returnValue;
}
public static int getToolbarHeight(Context context) {
final TypedArray styledAttributes = context.getTheme().obtainStyledAttributes(
new int[]{R.attr.actionBarSize});
int toolbarHeight = (int) styledAttributes.getDimension(0, 0);
styledAttributes.recycle();
return toolbarHeight;
}
}
I have added a viewpager addOnPageChangeListener:
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if (position == 0) {
FloatingActionButton floatingActionButton = (FloatingActionButton) findViewById(R.id.fab);
floatingActionButton.setVisibility(View.VISIBLE);
}
else
{
FloatingActionButton floatingActionButton = (FloatingActionButton) findViewById(R.id.fab);
floatingActionButton.setVisibility(View.GONE);
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
I only want the FAB to appear on the first page and disappear on all the other pages.
The code works but when I swipe down on the next page, the FAB appears after even though the visibility is set to gone. I think it has something to do with the behavior set for the FAB. Does anyone know why the FAB still become visible on a swipe down if the visibility is set to gone?