I am using FAB button along with RecyclerView in a Fragment. This Fragment is an instance of a TabViewPager. I am having a issue with the FAB button. I have placed the Recyc
This solution worked for me. Create a new class called CustomBehavior with the following code:
public class CustomBehavior extends CoordinatorLayout.Behavior<ViewPager> {
private int mActionBarHeight;
public CustomBehavior(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
init(context);
}
public CustomBehavior(Context context) {
init(context);
}
private void init(Context context) {
TypedValue tv = new TypedValue();
if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
mActionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
}
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, ViewPager child, View dependency) {
return dependency instanceof AppBarLayout;
}
public boolean onDependentViewChanged(CoordinatorLayout parent, ViewPager child, View dependency) {
offsetChildAsNeeded(parent, child, dependency);
return false;
}
private void offsetChildAsNeeded(CoordinatorLayout parent, View child, View dependency) {
if (child instanceof ViewPager) {
ViewPager viewPager = (ViewPager) child;
View list = viewPager.findViewById(R.id.recycler_view);
if (list != null) {
final CoordinatorLayout.Behavior behavior =
((CoordinatorLayout.LayoutParams) dependency.getLayoutParams()).getBehavior();
if (behavior instanceof AppBarLayout.Behavior) {
final AppBarLayout.Behavior ablBehavior = (AppBarLayout.Behavior) behavior;
AppBarLayout appBarLayout = (AppBarLayout) dependency;
ViewCompat.setTranslationY(list, ablBehavior.getTopAndBottomOffset()
+ appBarLayout.getTotalScrollRange()
+ mActionBarHeight);
}
}
}
}
}
Now, assign the custom behavior class to viewpager widget in the xml file
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="yourpackage.CustomBehavior"
/>
I am facing the same issues with view pager 1st Fragment FAB buttons is showing below the screen and on scroll its show. But after some findings I found that I have written
app:layout_behavior="@string/appbar_scrolling_view_behavior"
in ViewPager in CoordinatorLayout. So after removing this scroll behaviour FAB position issues is resolved.
Please check my Implementation working correctly :
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@string/app_name"
android:textColor="@color/textPrimary"
android:textSize="18sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@string/str_toolbar_subtittle"
android:textColor="@color/textPrimary"
android:textSize="14sp" />
</LinearLayout>
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="?attr/colorPrimary"
app:tabGravity="fill"
app:tabIndicatorColor="@color/colorAccent"
app:tabSelectedTextColor="@color/errorColor"
app:tabTextColor="@color/white" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/app_bar" />
</android.support.design.widget.CoordinatorLayout>
I kind of did what Gabriele suggested with moving the FAB to the containing activity. Also you will need to update the FAB's color/clickListener in onTabSelected:
public class MainActivity extends AppCompatActivity implements TabLayout.OnTabSelectedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
...
setFloatingActionButtonForImagesTab();
}
...
@Override
public void onTabSelected(final TabLayout.Tab tab) {
switch (tab.getPosition()) {
case 0:
setFloatingActionButtonForImagesTab();
break;
case 1:
setFloatingActionButtonForMusicTab();
break;
case 2:
setFloatingActionButtonForVideoTab();
break;
}
}
...
}
and then in the setup function just set the color and click listener:
private void setFloatingActionButtonForImagesTab() {
myViewPager.setCurrentItem(0);
floatingActionButton.setBackgroundTintList(getResources().getColorStateList(R.color.purple));
floatingActionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(coordinatorLayout, "images", Snackbar.LENGTH_LONG)
.show();
}
});
}
Make note of the call to setCurrentItem
above. It is required now that you are implementing TabLayout.OnTabSelectedListener
.
app:layout_scrollFlags="scroll|enterAlways"
. Credits to JDev at how to avoid hiding the tabs when scrolled down?I was having the same issue where the requirement was to show FAB in a fragment. What I did is just removed the line from toolbar
app:layout_scrollFlags="scroll|enterAlways"
You can check my layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/appbar_padding_top"
android:background="@color/white"
app:elevation="0dp"
android:elevation="0dp"
>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar_main"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_weight="1"
android:background="@color/white"
app:title="@string/app_name">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="@+id/tabs_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
</android.support.design.widget.TabLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
I just ran into the same problem. Unfortunately, I don't have an answer for you, but some addon point.
It is not that the button is pushed down, it's the whole fragment been pushed down. I haven't test it so far, but I imagine, if there is a way that enables you to see the size of the fragment page, you'll see it doesn't end at the bottom of the screen as it should be.
for possible solution, I'm think about adding a padding of size "?attr/actionBarSize" at the bottom.
I'll test this, and post back when finish
update: As I used a border of 80 dp, get a screen shot (I dont have 10 reputation to post a screen shot, wth)
workaround:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<include
layout="@layout/toolbar"/>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="@+id/fragment_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/border"
android:layout_marginTop="?attr/actionBarSize"
>
<!--android:paddingBottom="?attr/actionBarSize"-->
<!--app:layout_behavior="@string/appbar_scrolling_view_behavior"-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/border"></LinearLayout>
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.derek.hianthy.mydiary.ui.BaseFragment"
tools:layout="@layout/layout"
android:background="@drawable/border"
/>
</FrameLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fabBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_marginBottom="@dimen/fab_margin_bottom"
android:layout_marginRight="@dimen/fab_margin_right"
android:src="@drawable/ic_action_add"
app:borderWidth="0dp"
app:fabSize="normal"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="false"
android:layout_alignParentLeft="false" />
</android.support.design.widget.CoordinatorLayout>
notic app:layout_behavior="@string/appbar_scrolling_view_behavior" been taken out. result