18
  1. I am Using Snack bar and FAB in my application Same Page,Whenever Snackbar is Showing Floating Action button not Going up.

  2. I am Using Third Party library for attachToListView works fine

     import com.melnykov.fab.FloatingActionButton;
    

if I am using Default library "cannot be resolved attachToListView"

import android.support.design.widget.FloatingActionButton;

My Need:

  1. attachToListView Should Work(For When Listview Scroling Down FAB will be Disappear).

  2. Whenever Snackbar is Showing Floating Action button Should Go up.

Help me How to Solve this Issue.

Third Party Library Link

EDIT :1

I Removed Third Party Library added Default Import (import android.support.design.widget.FloatingActionButton),FAB is Going Up but Attachtolistivew not Resolved.

EDIT :2

I Used Listview In my activity ,with FAB and Snackbar. So i need Both Options Like FAB Go up When Snackbar Opens and when Listview is Scrolling down Should hide FAB.

My SnackBar Code:

 Snackbar snack = Snackbar.make(fab1, " Successfully ...!",Snackbar.LENGTH_SHORT);
                    View snackbarView = snack.getView();
                    snackbarView.setBackgroundColor(Color.parseColor("#f44336"));
                    snack.show();

Main.java

import com.melnykov.fab.FloatingActionButton;
     @Override
        protected void onCreate(Bundle savedInstanceState) 
    {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.fabview);
    
            fab1 = (FloatingActionButton) findViewById(R.id.fab);
    
            fab1.setShadow(true);
            //fab.attachToListView(provider_service_list);
    
            //FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
            fab1.attachToListView(listViewData, new ScrollDirectionListener()
            {
                @Override
                public void onScrollDown() {
                    Log.d("ListViewFragment", "onScrollDown()");
                }
    
                @Override
                public void onScrollUp() {
                    Log.d("ListViewFragment", "onScrollUp()");
                }
            }, new AbsListView.OnScrollListener() {
                @Override
                public void onScrollStateChanged(AbsListView view, int scrollState) {
                    Log.d("ListViewFragment", "onScrollStateChanged()");
                }
    
                @Override
                public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                    Log.d("ListViewFragment", "onScroll()");
                }
            });
    
    }

fabview.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app78="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.support.design.widget.CoordinatorLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/coordinatorlayout">
    
            <com.melnykov.fab.FloatingActionButton
                android:id="@+id/fab"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom|right"
                android:layout_margin="@dimen/fab_margin"
                android:src="@drawable/ic_add_white_24dp"
                app78:fab_colorNormal="@color/accent"
                app78:fab_colorPressed="@color/accent_pressed"
                app78:fab_colorRipple="@color/ripple"
                app78:fabSize="normal"
                app78:borderWidth="0dp"
                android:layout_marginBottom="@dimen/fab_margin_bottom"
                android:layout_marginRight="@dimen/fab_margin_right"
                />
    
        </android.support.design.widget.CoordinatorLayout>
   </RelativeLayout>
Kumar
  • 969
  • 2
  • 22
  • 56

4 Answers4

10

Your requirements are:

1)When Listview Scroling Down FAB will be Disappear

2)Whenever Snackbar is Showing Floating Action button Should Go up.

Now examine your solutions:

1) If you are going to use design support library fab you will only satisfy constraint number 2.

2) If you are going to use third party fab you will only satisfy constraint number 1.

You can satisfy your 2 constraints by either manipulating third party library and adding animation when you are going to show snackbar or by manipulating ListView to put it inside CordinateLayout and then make fab disappear when ListView is Scrolling down.

My solution:

Fastest solution is changing your ListView to RecyclerView and using CordinateLayout and design support library fab. now you can achieve #2. (RecyclerView is more powerful widget than ListView. Why do I have to do that? because CordinateLayout creates your animation and it works only by any scrolling widget that implements NestedScrolling interface. the ListView from LOLLIPOP and up implements that interface. if your min SDK is lower than LOLLIPOP you have to use RecyclerView).

for number #1 you can use below code:

 recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                if (dy > 0 && fab.isShown())
                    fab.hide();
            }

            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {

                if (newState ==  RecyclerView.SCROLL_STATE_IDLE) {
                    fab.show();
                }
                super.onScrollStateChanged(recyclerView, newState);
            }
        }); 

your layout would be:

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        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:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_scrollFlags="scroll|enterAlways|snap"/>

    </android.support.design.widget.AppBarLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />


    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        android:src="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>
  • most accurate but a little logic error, if user swipes down it will hide the FAB but as soon as user removes finger or releases touch it will show again the FAB. Very little change is needed just add another if else case inside onScrolled() method. @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { if (dy > 0 && mFAB.isShown()){ mFAB.hide(); } else if (dy < 0 && mFAB.getVisibility() != View.VISIBLE) { mFAB.show(); } } – mfaisalhyder May 24 '16 at 09:57
8

We have 2 ways to do this:

Whenever Snackbar is Showing Floating Action button Should Go up.

You are using 3rd lib : import com.melnykov.fab.FloatingActionButton; so you need to implement custom behavior:

  1. xml file:

    <com.melnykov.fab.FloatingActionButton xmlns:fab="http://schemas.android.com/apk/res-auto"
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="16dp"
        android:src="@drawable/sort_variant"
        fab:fab_colorNormal="@color/colorPrimary"
        fab:fab_colorPressed="@color/colorPrimaryDark"
        fab:fab_colorRipple="@color/colorAccent"
        app:layout_behavior="com.simpleapp.tvtan.testcustomfloatingactionbutton.SnackBarBehavior"/>
    

  2. Custom behavior class:

    public class SnackBarBehavior extends CoordinatorLayout.Behavior<FloatingActionButton> {
    public SnackBarBehavior() {
    }
    
    public SnackBarBehavior(Context context, AttributeSet attrs) {
    super(context, attrs);
    }
    
    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
    return dependency instanceof Snackbar.SnackbarLayout;
    }
    
    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
    float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight());
    child.setTranslationY(translationY);
    return true;
      }
    }
    

attachToListView Should Work(For When Listview Scroling Down FAB will be Disappear)

Or if you want to use Floating Action Button from Design Library, you can implement with RecyclerView like this, you need to implement custom behavior too:

  1. xml file:

<android.support.v7.widget.RecyclerView
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/sort_variant"
    android:layout_gravity="bottom|end"
    android:layout_margin="16dp"
    app:layout_behavior="com.simpleapp.tvtan.testcustomfloatingactionbutton.ScrollBehavior"/>

  1. Your behavior class:

    public class ScrollBehavior extends FloatingActionButton.Behavior {
    
    public ScrollBehavior(Context context, AttributeSet attrs) {
    super();
    }
    
    @Override
    public void onNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
    super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
    if (dyConsumed > 0) {
        CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
        int fab_bottomMargin = layoutParams.bottomMargin;
        child.animate().translationY(child.getHeight() + fab_bottomMargin).setInterpolator(new LinearInterpolator()).start();
    } else if (dyConsumed < 0) {
        child.animate().translationY(0).setInterpolator(new LinearInterpolator()).start();
        }
      }
    
    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View directTargetChild, View target, int nestedScrollAxes) {
    return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL;
      }
    }
    

Your parent layout need to be a CoordinatorLayout p/s: I don't know why my xml code did not show all text from my file, so i can not show full xml file for you.

Martin Klinke
  • 7,294
  • 5
  • 42
  • 64
Norutan
  • 1,480
  • 2
  • 14
  • 27
  • `SnackBarBehavior` works as expected,but add an override for `onDependentViewRemoved()` that simply sets `child.setTranslationY(0);` after the call to super. This moves the custom FAB back to it's original position when the Snackbar is dismissed. – Unknownweirdo Aug 25 '17 at 13:26
2

You need to use <android.support.design.widget.CoordinatorLayout as the root tag in your layout file. Only then you'll be able to get your desired result.

STEP: 1

 <?xml version="1.0" encoding="utf-8"?>
 <android.support.design.widget.CoordinatorLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app78="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/myCoordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">              

        <com.melnykov.fab.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|right"
            android:layout_margin="@dimen/fab_margin"
            android:src="@drawable/ic_add_white_24dp"
            app78:fab_colorNormal="@color/accent"
            app78:fab_colorPressed="@color/accent_pressed"
            app78:fab_colorRipple="@color/ripple"
            app78:fabSize="normal"
            app78:borderWidth="0dp"
            android:layout_marginBottom="@dimen/fab_margin_bottom"
            android:layout_marginRight="@dimen/fab_margin_right"
            />

  </android.support.design.widget.CoordinatorLayout>    

STEP 2:

CoordinatorLayout myCoordinatorLayout = (CoordinatorLayout)findViewById(R.id.mycoordinatorLayout);

Snackbar snack = Snackbar.make(myCoordinatorLayout,"Successfully.!",Snackbar.LENGTH_SHORT);

For more info check out Android dev blog.

halfer
  • 19,824
  • 17
  • 99
  • 186
Sjd
  • 1,261
  • 1
  • 12
  • 11
1

to use floating action button you should use this structure for your xml-

<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.afixi.prasenjeetpati.trailone.MainActivity">

<include layout="@layout/content_main" />

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    android:layout_margin="@dimen/fab_margin"
    android:src="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>

the content_main should be your main content where you define all your texts and buttons and other content. the coordinator layout should contain this much of code . the extra code it might contain is toolbar or navigation drawer. the main content should always be another xml file.

Mainactivity

 FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });
Sagar Nayak
  • 2,138
  • 2
  • 19
  • 52