How to show/hide FloatingActionButton when scrolling RecyclerView

Từ khi FloatingActionButton được Google đưa ra trong gói support design của mình thì nó được sử dụng khá phổ biến. Vấn đề xảy ra là FloatingActionButton sẽ che mất một góc nhỏ màn hình, đặc biệt là khi sử dụng các list như ListView, GridView, RecyclerView, ..., điều này làm cho trải nghiệm người dùng không được tốt. Trong bài viết lần này mình sẽ hướng dẫn các bạn show/hide FloatingActionButton khi scroll RecyclerView. Đương nhiên vấn đề này có nhiều cách, các bạn có thể tìm hiểu trên mạng nhưng mình sẽ giới thiệu/hướng dẫn một cách đơn giản nhất. Để cho các bạn dễ theo dõi, mình sẽ tạo một project nhỏ để demo và có kết quả luôn 😄

Bước 1: Tạo project

Cấu trúc thư mục sẽ như sau

Bước 2: Thêm gói thư viện design

Thêm gói thư viện compile 'com.android.support:design:25.3.0' vào dependencies của file app/build.gradle

Bước 3: Tạo RecyclerView và FloatActionButton trong activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <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:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_margin="16dp"
        app:backgroundTint="@color/color_accent"
        app:srcCompat="@android:drawable/ic_dialog_email"/>

</RelativeLayout>

Bước 4: Tạo TextView trong item_recycler_view.xml

Ở đây mình chỉ để item hiển thị là 1 TextView cho đơn giản 😄

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/text_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="10dp"
    android:textSize="15sp"/>

Bước 5: Tạo Adapter cho RecyclerView

class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder> {
    private List<String> mList = new ArrayList<>();

    ListAdapter(List<String> list) {
        if (list != null) mList.addAll(list);
    }

    static class ViewHolder extends RecyclerView.ViewHolder {
        TextView textView;

        ViewHolder(View v) {
            super(v);
            textView = (TextView) v.findViewById(R.id.text_view);
        }
    }

    @Override
    public ListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.item_recycler_view, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ListAdapter.ViewHolder holder, int position) {
        holder.textView.setText(mList.get(position));
    }

    @Override
    public int getItemCount() {
        return mList.size();
    }
}

Bước 6: Tạo dữ liệu và hiển thị lên RecyclerView

Tạo các field cần thiết trong MainActivity.java

    private List<String> mList = new ArrayList<>();
    private RecyclerView mRecyclerView;
    private FloatingActionButton mActionButton;

Tạo method setupView()

    private void setUpView() {
        mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        mActionButton = (FloatingActionButton) findViewById(R.id.fab);
    }

Tạo method fakeData() để tạo dữ liệu cho RecyclerView

    private void fakeData() {
        Random random = new Random();
        for (int i = 0; i < 100; i++)
            mList.add(String.valueOf(random.nextInt(100)));
    }

Tạo method setUpRecyclerView() set adapter cho RecyclerView

    private void setUpRecyclerView() {
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager
            .VERTICAL, false));
        mRecyclerView.setHasFixedSize(true);
        ListAdapter listAdapter = new ListAdapter(mList);
        mRecyclerView.setAdapter(listAdapter);
    }

Tạo method showHideFabWhenScroll() để show/hide FloatingActionButton khi scroll

    private void showHideWhenScroll() {
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                //dy > 0: scroll up; dy < 0: scroll down
                if (dy > 0) mActionButton.hide();
                else mActionButton.show();
                super.onScrolled(recyclerView, dx, dy);
            }
        });
    }

Đặt các method vừa tạo vào onCreate() của MainActivity

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setUpView();
        fakeData();
        setUpRecyclerView();
        showHideWhenScroll();
    }

Bước 7: Demo và run chương trình

Các bạn có thể xem source code tại My Repository

Cảm ơn các bạn đã đọc bài viết!