Ẩn/Hiện thanh toolbar khi scroll trên recycle view
This post hasn't been updated for 7 years
Tạo recycle view
Để control được việc ẩn / hiện của toolbar hoặc bất kì một view nào trong quá trình scroll recycleview thì việc đầu tiên chúng ta cần làm là tạo một recycle view và một thanh toolbar đơn giản. Đầu tiên là việc import thư viện:
.....
dataBinding {
enabled = true
}
.....
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.2.0'
compile 'com.android.support:recyclerview-v7:25.1.1'
compile 'com.android.support:cardview-v7:25.2.0'
testCompile 'junit:junit:4.12'
}
Tạo adapter cho recycleview Adapter.java
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
private String[] mItems;
private LayoutInflater mLayoutInflater;
public Adapter(String[] items) {
mItems = items;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (mLayoutInflater == null) mLayoutInflater = LayoutInflater.from(parent.getContext());
ItemRecycleViewBinding binding =
ItemRecycleViewBinding.inflate(mLayoutInflater, parent, false);
return new Adapter.ViewHolder(binding);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(position);
}
@Override
public int getItemCount() {
return mItems == null ? 0 : mItems.length;
}
public class ViewHolder extends RecyclerView.ViewHolder {
private ItemRecycleViewBinding mBinding;
public ViewHolder(ItemRecycleViewBinding binding) {
super(binding.getRoot());
mBinding = binding;
}
private void bind(int pos) {
mBinding.setText(mItems[pos]);
mBinding.executePendingBindings();
}
}
}
Custom việc init Recycleview bằng databinding BindingUtil.java
public class BindingUtil {
@BindingAdapter({"adapter", "context"})
public static void initRecycleview(RecyclerView recyclerView, Adapter adapter,
AppCompatActivity activity) {
if (recyclerView == null || adapter == null) return;
recyclerView.setLayoutManager(new LinearLayoutManager(activity));
recyclerView.setAdapter(adapter);
}
}
Tạo layout cho MainActivity.java activity_main.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="activity"
type="beemusic.framgia.com.controlscrollrecycleview.MainActivity"/>
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
bind:adapter="@{activity.adapter}"
bind:context="@{activity}"/>
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
android:title="@string/app_name"/>
</FrameLayout>
</layout>
Tạo layout item_recycle_view.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="text"
type="String"/>
</data>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="8dp"
app:cardCornerRadius="4dp"
app:cardElevation="@dimen/dp_2">
<TextView
android:layout_width="match_parent"
android:layout_height="?attr/listPreferredItemHeight"
android:gravity="center"
android:text="@{text}"/>
</android.support.v7.widget.CardView>
</layout>
Control việc ẩn/ hiện toolbar
Để control được việc ẩn hiện thanh toolbar, ta viết lại lớp RecyclerView.OnScrollListener ControlScrollListener.java
public abstract class ControlScrollListener extends RecyclerView.OnScrollListener {
private static final int HIDE_THRESHOLD = 20;
private int mScrolledDistance = 0;
private boolean mVisible = true;
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int firstVisibleItem =
((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
//show views if first item is first visible position and views are hidden
if (firstVisibleItem == 0) {
if (!mVisible) {
onShow();
mVisible = true;
}
} else {
if (mScrolledDistance > HIDE_THRESHOLD && mVisible) {
onHide();
mVisible = false;
mScrolledDistance = 0;
} else if (mScrolledDistance < -HIDE_THRESHOLD && !mVisible) {
onShow();
mVisible = true;
mScrolledDistance = 0;
}
}
if ((mVisible && dy > 0) || (!mVisible && dy < 0)) {
mScrolledDistance += dy;
}
}
public abstract void onHide();
public abstract void onShow();
}
Bây giờ, trong file BindingUtil.java, chúng ta sẽ tạo callback để control bằng việc khởi tạo một đối tượng ControlScrollListener thực sự cho recycleview.
@BindingAdapter({"adapter", "context", "toolbar"})
public static void initRecycleview(RecyclerView recyclerView, Adapter adapter,
AppCompatActivity activity, final Toolbar toolbar) {
if (recyclerView == null || adapter == null) return;
recyclerView.setLayoutManager(new LinearLayoutManager(activity));
recyclerView.setAdapter(adapter);
recyclerView.setOnScrollListener(new ControlScrollListener() {
@Override
public void onHide() {
toolbar.animate().translationY(-toolbar.getHeight())
.setInterpolator(new AccelerateInterpolator(2));
}
@Override
public void onShow() {
toolbar.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2));
}
});
}
Vậy là chúng ta đã hoàn tất project. Các bạn có thể tham khảo source code tại đây
All Rights Reserved