我的全部文章整理在此篇,將陸續更新收錄:知無涯,行者之路莫言終(個人編程之路)android
RecyclerView零點突破(基本使用篇)
RecyclerView零點突破(動畫+邊線篇)
RecyclerView零點突破(自定義LayoutManager篇)--待完成
RecyclerView零點突破(源碼分析篇)--待完成編程
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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="wrap_content">
<ImageView
android:id="@+id/id_iv_qq_head"
android:layout_width="@dimen/item_qq_msg_iv_size"
android:layout_height="@dimen/item_qq_msg_iv_size"
android:layout_marginStart="@dimen/dp_16"
android:layout_marginTop="@dimen/dp_8"
android:layout_marginBottom="@dimen/dp_8"
android:src="@mipmap/head"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<android.support.constraint.ConstraintLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_16"
android:layout_marginEnd="@dimen/dp_16"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/id_iv_qq_head"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/id_tv_qq_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="張風捷特烈"
android:textSize="@dimen/sp_16"/>
<TextView
android:id="@+id/id_tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2018-11-30"
android:textSize="@dimen/sp_12"
app:layout_constraintBottom_toBottomOf="@id/id_tv_qq_name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/id_tv_qq_name"/>
<TextView
android:id="@+id/id_tv_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_4"
android:text="天下無雙"
android:textColor="#aaa"
android:textSize="@dimen/sp_12"
app:layout_constraintTop_toBottomOf="@id/id_tv_qq_name"/>
<com.toly1994.test.view.CountTextView
android:id="@+id/id_ctv_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="@id/id_tv_info"
app:layout_constraintEnd_toEndOf="@+id/id_tv_time"
app:layout_constraintTop_toTopOf="@+id/id_tv_info"
app:z_bg_color="@color/red"
app:z_ctv_font_size="@dimen/sp_14"
app:z_ctv_num="10"/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
複製代碼
至於爲何要ViewHolder,這裏簡單的講一下:
item的佈局裏面有控件,將這些控件封裝起來放在一個類中,使用的時候至關於對成員變量的使用
避免用一次找一次。就像你經過身份證(id)去找人,不用ViewHolder的話,你每次用他都要去找一次
使用ViewHolder至關於把他放旁邊放着,使用的時候直接拿,就不須要用id再去找他了bash
/**
* ViewHolder
*/
class MyViewHolder extends RecyclerView.ViewHolder {
private TextView mItemTV;
public MyViewHolder(View itemView) {
super(itemView);
mItemTV = itemView.findViewById(R.id.id_tv_qq_name);
}
}
複製代碼
/**
* 做者:張風捷特烈<br/>
* 時間:2018/12/2 0002:9:22<br/>
* 郵箱:1981462002@qq.com<br/>
* 說明:qq信息列表Adapter
*/
public class QQRvAdapter extends RecyclerView.Adapter<QQRvAdapter.MyViewHolder> {
private static final String TAG = "TolyRvAdapter";
private List<String> mData;
private Context mContext;
public QQRvAdapter(List<String> data) {
mData = data;
}
@NonNull
@Override//將item佈局文件與ViewHolder結合
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
mContext = parent.getContext();
View view = LayoutInflater.from(mContext)
.inflate(R.layout.item_qq_msg, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.mItemTV.setText(mData.get(position));
}
@Override
public int getItemCount() {
return mData.size();
}
}
複製代碼
mIdRvContent.addItemDecoration(new RecycleViewDivider(this, LinearLayoutManager.VERTICAL));//分割線
mACAdapter = new QQRvAdapter(DataUtils.getRandomName(60, true));//初始化適配器
mIdRvContent.setAdapter(mACAdapter);//設置適配器
mIdRvContent.setLayoutManager(new LinearLayoutManager(this));
複製代碼
瀑布流 | 網格流 |
---|---|
![]() |
![]() |
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
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="wrap_content"
android:layout_margin="@dimen/dp_8"
app:cardCornerRadius="@dimen/dp_8"
app:cardElevation="@dimen/dp_4"
app:cardPreventCornerOverlap="false">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/id_iv_goods"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitStart"
android:src="@mipmap/pic1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/id_iv_info"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/dp_8"
android:text="藍夜皮膚,2030年爆款,限額三件,先到先得,售完爲止"
android:textColor="@color/black"
android:textSize="@dimen/sp_12"
app:layout_constraintEnd_toEndOf="@id/id_iv_goods"
app:layout_constraintStart_toStartOf="@id/id_iv_goods"
app:layout_constraintTop_toBottomOf="@id/id_iv_goods"/>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/dp_8"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/id_iv_info">
<TextView
android:id="@+id/id_yang"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dp_2"
android:text="¥"
android:textColor="@color/red"
android:textSize="@dimen/sp_12"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:id="@+id/id_goods_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="99999"
android:textColor="@color/red"
android:textSize="@dimen/sp_18"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/id_yang"/>
<TextView
android:id="@+id/id_goods_buy_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_8"
android:text="1人已付款"
android:textColor="@color/gray_8f"
android:textSize="@dimen/sp_12"
app:layout_constraintBottom_toBottomOf="@id/id_yang"
app:layout_constraintStart_toEndOf="@id/id_goods_price"/>
<ImageView
android:id="@+id/id_iv_btn_more"
android:layout_width="10dp"
android:layout_height="10dp"
android:src="@drawable/icon_more_h"
android:tint="@color/gray_8f"
app:layout_constraintBottom_toBottomOf="@id/id_goods_buy_num"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/id_goods_buy_num"/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
複製代碼
/**
* 做者:張風捷特烈<br/>
* 時間:2018/12/4 0004:8:43<br/>
* 郵箱:1981462002@qq.com<br/>
* 說明:商品的實體類
*/
public class GoodsBean {
private int imgId; //資源id
private String info; //詳情
private float price;//價格
private int buyNum;//購買人數
private String ticket;//優惠券
//其餘,略....
}
複製代碼
public class BeanFactory {
public static List<GoodsBean> getGoodsBean() {
List<GoodsBean> beans = new ArrayList<>();
for (int i = 0; i < 4; i++) {
beans.add(new GoodsBean(R.mipmap.pic4, "混沌戰士,等比例人形,附加刀及盔甲,2030年爆款,限額三百件,先到先得,售完爲止", 6666, 277, "店鋪優惠,滿100送10"));
beans.add(new GoodsBean(R.mipmap.pic1, "藍夜皮膚,2030年爆款,限額三件,先到先得,售完爲止", 99999, 2));
beans.add(new GoodsBean(R.mipmap.pic3, "古典美女,等比例人形,2030年爆款,限額三百件,先到先得,售完爲止", 999, 177, "店鋪優惠,滿100送1000"));
beans.add(new GoodsBean(R.mipmap.pic6, "珍藏,非賣品", 9999999, 1));
beans.add(new GoodsBean(R.mipmap.pic2, "黑夜皮膚,附加魔法加成,2030年爆款,限額三百件,先到先得,售完爲止", 8888, 277, "店鋪優惠,滿100送100000"));
beans.add(new GoodsBean(R.mipmap.pic5, "買洞爺湖送銀時,只要998,絕對良心價,2030年爆款,限額三百件,先到先得,售完爲止", 998, 277, "店鋪優惠,滿100送100000"));
}
return beans;
}
}
複製代碼
public class GoodsAdapter extends RecyclerView.Adapter<GoodsAdapter.MyViewHolder> {
private Context mContext;
private List<GoodsBean> mData;
public GoodsAdapter(List<GoodsBean> data) {
mData = data;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
mContext = parent.getContext();
View view = LayoutInflater.from(mContext).inflate(R.layout.item_goods_list, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
GoodsBean str = mData.get(position);
holder.mIdIvGoods.setImageResource(str.getImgId());
holder.mIdGoodsPrice.setText(str.getPrice()+"");
holder.mIdIvInfo.setText(str.getInfo());
holder.mIdGoodsBuyNum.setText(str.getBuyNum()+"人已付款");
}
@Override
public int getItemCount() {
return mData.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
public ImageView mIdIvGoods;
public TextView mIdYang;
public TextView mIdGoodsPrice;
public TextView mIdIvInfo;
public TextView mIdGoodsBuyNum;
public ImageView mIdIvBtnMore;
public MyViewHolder(View itemView) {
super(itemView);
mIdIvGoods = itemView.findViewById(R.id.id_iv_goods);
mIdYang = itemView.findViewById(R.id.id_yang);
mIdGoodsPrice = itemView.findViewById(R.id.id_goods_price);
mIdIvInfo = itemView.findViewById(R.id.id_iv_info);
mIdGoodsBuyNum = itemView.findViewById(R.id.id_goods_buy_num);
mIdIvBtnMore = itemView.findViewById(R.id.id_iv_btn_more);
}
}
}
複製代碼
//初始化RecyclerView
@BindView(R.id.id_rv_goods)
RecyclerView mIdRvGoods;
//使用
mIdRvGoods.setAdapter(new GoodsAdapter(BeanFactory.getGoodsBean()));
mIdRvGoods.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
複製代碼
//網格流
mIdRvGoods.setLayoutManager(
new GridLayoutManager(this, 3, GridLayoutManager.VERTICAL, false));
複製代碼
//爲holder.itemView(即條目的View)設置點擊事件
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
String name = mData.get(position);
holder.mItemTV.setText(name);
holder.itemView.setOnClickListener(v -> {
ToastUtil.show(mContext, "第" + position + "個:" + name);
});
}
複製代碼
//item的最頂層設置:
android:background="?android:attr/selectableItemBackground"
複製代碼
番外
:你也能夠自定義水波紋效果(安卓5.0+)微信
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#8834C4F2"><!-- press和水波紋的顏色 -->
<item>
<shape
android:innerRadius="5dp"
android:shape="rectangle">
<solid android:color="@color/white"/>
<corners android:radius="1dp"/>
</shape>
</item>
</ripple>
複製代碼
好吧,炫到晃眼app
刪除條目 | 移動條目 |
---|---|
![]() |
![]() |
AdapterItemOp
/**
* 做者:張風捷特烈<br/>
* 時間:2018/12/3 0003:20:20<br/>
* 郵箱:1981462002@qq.com<br/>
* 說明:Item 操做的接口
*/
public interface AdapterItemOp<T> {
/**
* 交換條目
*
* @param from 起點
* @param to 終點
*/
void onItemMove(int from, int to);
/**
* 刪除條目
*
* @param position 位置
*/
void onItemDelete(int position);
}
複製代碼
/**
* 做者:張風捷特烈<br/>
* 時間:2018/12/3 0003:20:20<br/>
* 郵箱:1981462002@qq.com<br/>
* 說明:條目觸摸時的回調
*/
public class ItemTouchCallback extends ItemTouchHelper.Callback {
private AdapterItemOp mAdapter;//操做接口
public ItemTouchCallback(AdapterItemOp adapter) {
mAdapter = adapter;
}
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
//上下左右拖動
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN |
ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT;
//可向左滑動---刪除
int swipeFlags = ItemTouchHelper.LEFT;
return makeMovementFlags(dragFlags, swipeFlags);
}
@Override//長按拖動
public boolean isLongPressDragEnabled() {
return true;
}
@Override//滑動刪除
public boolean isItemViewSwipeEnabled() {
return true;
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
//移動時:---交換兩個ViewHolder的位置
mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return true;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
//滑動刪除時:---
mAdapter.onItemDelete(viewHolder.getAdapterPosition());
}
}
複製代碼
用接口爲了方便使用,在GoodsAdapter裏直接寫操做方法,ItemTouchCallback傳入GoodsAdapter也能夠
不過當其餘的Adapter也須要操做時,要修改ItemTouchCallback,因此二者耦合度過高dom
@Override
public void onItemMove(int from, int to) {
//交換位置
ToastUtil.showAtOnce(mContext, "已交換:" + from + "和" + to + "的位置");
Collections.swap(mData, from, to);
notifyItemMoved(from, to);//刷新移動數據---將不刷新position
}
@Override
public void onItemDelete(int position) {
//移除數據
ToastUtil.showAtOnce(mContext, "已刪除:" + position);
mData.remove(position);
notifyItemRemoved(position);//刷新移除數據---將不刷新position
}
複製代碼
注:能夠將addItem方法也放在操做接口
注意:notifyItemRemoved
、notifyItemInserted
和notifyItemMoved
調用時,item所在的position是不更新的ide
public void addItem(int position, GoodsBean bean) {
mData.add(position, bean);
notifyItemInserted(position);//刷新插入數據---將不刷新position
if (position == 0) {
mRecyclerView.scrollToPosition(0);
}
}
複製代碼
多個條目 | 類型分析 |
---|---|
![]() |
![]() |
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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="wrap_content"
android:layout_marginBottom="@dimen/dp_16">
<ImageView
android:id="@+id/id_iv_chat_head"
android:layout_width="@dimen/item_qq_msg_iv_size"
android:layout_height="@dimen/item_qq_msg_iv_size"
android:layout_marginEnd="@dimen/dp_8"
android:layout_marginBottom="@dimen/dp_8"
android:src="@mipmap/head"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/id_tv_chat_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/dp_4"
android:background="@mipmap/me"
android:gravity="center"
android:maxWidth="280dp"
android:text="天下無雙"
android:textColor="@color/black"
android:textSize="@dimen/sp_16"
app:layout_constraintEnd_toStartOf="@+id/id_iv_chat_head"
app:layout_constraintTop_toTopOf="@+id/id_iv_chat_head"/>
</android.support.constraint.ConstraintLayout>
複製代碼
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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="wrap_content"
android:layout_marginBottom="@dimen/dp_16">
<ImageView
android:id="@+id/id_iv_chat_head"
android:layout_width="@dimen/item_qq_msg_iv_size"
android:layout_height="@dimen/item_qq_msg_iv_size"
android:layout_marginStart="@dimen/dp_8"
android:layout_marginBottom="@dimen/dp_8"
android:src="@mipmap/icon_gql"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/id_tv_chat_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_4"
android:background="@mipmap/he"
android:gravity="center"
android:maxWidth="280dp"
android:text="天下無雙"
android:textColor="@color/black"
android:textSize="@dimen/sp_16"
app:layout_constraintStart_toEndOf="@+id/id_iv_chat_head"
app:layout_constraintTop_toTopOf="@+id/id_iv_chat_head"/>
</android.support.constraint.ConstraintLayout>
複製代碼
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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_marginBottom="@dimen/dp_8"
android:layout_height="wrap_content">
<TextView
android:id="@+id/id_tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="@drawable/shape_round_rect"
android:padding="@dimen/dp_4"
android:text="12月1日 早上11:45"
android:textColor="@color/white"
android:textSize="@dimen/sp_14"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
</android.support.constraint.ConstraintLayout>
複製代碼
番外
:圓角矩形的shape源碼分析
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#88888888"/>
<corners android:radius="4dp"/>
</shape>
複製代碼
/**
* 做者:張風捷特烈<br/>
* 時間:2018/12/3 0003:16:22<br/>
* 郵箱:1981462002@qq.com<br/>
* 說明:消息的實體類
*/
public class MsgBean {
private int type;//類型:0 我 1 他 2 時間
private String msg;//信息體
//get、set、構造,略...
}
複製代碼
注:聊天數據從:
《匆匆》
中獲取0~100個字隨機拼接佈局
/**
* 獲取隨機聊天消息
* @return
*/
public static List<MsgBean> getMsgBeans() {
List<MsgBean> beans = new ArrayList<>();
for (int i = 0; i < 60; i++) {
if (i % 10 == 0) {
beans.add(new MsgBean(2, ""));
continue;
}
beans.add(new MsgBean(ZRandom.rangeInt(0, 1),
ZRandom.randomChar(ZData.congcong, 100)));
}
return beans;
}
複製代碼
/**
* 做者:張風捷特烈<br/>
* 時間:2018/12/2 0002:9:22<br/>
* 郵箱:1981462002@qq.com<br/>
* 說明:聊天的適配器
*/
public class ChatRvAdapter extends RecyclerView.Adapter<ChatRvAdapter.MyViewHolder> {
private static final String TAG = "TolyRvAdapter";
private List<MsgBean> mData;
private Context mContext;
public ChatRvAdapter(List<MsgBean> data) {
mData = data;
}
@NonNull
@Override//將item佈局文件與ViewHolder結合
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
mContext = parent.getContext();
View view = null;
switch (viewType) {//對不一樣的viewType加載不一樣的佈局
case 0:
view = LayoutInflater.from(mContext)
.inflate(R.layout.item_chat_me, parent, false);
break;
case 1:
view = LayoutInflater.from(mContext)
.inflate(R.layout.item_chat_he, parent, false);
break;
case 2:
view = LayoutInflater.from(mContext)
.inflate(R.layout.item_chat_time, parent, false);
break;
}
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
MsgBean msgBean = mData.get(position);
switch (msgBean.getType()) {//對不一樣的viewType設置不一樣的數據
case 0:
case 1:
holder.mItemTV.setText(msgBean.getMsg());
break;
case 2:
String time = new SimpleDateFormat("MM月dd日 a HH:mm", Locale.CHINA)
.format(System.currentTimeMillis());
holder.mItemTvTime.setText(time);
break;
}
}
@Override
public int getItemCount() {
return mData.size();
}
@Override
public int getItemViewType(int position) {//返回條目種類viewType
return mData.get(position).getType();
}
/**
* ViewHolder
*/
class MyViewHolder extends RecyclerView.ViewHolder {
private TextView mItemTV;
private TextView mItemTvTime;
public MyViewHolder(View itemView) {
super(itemView);
mItemTV = itemView.findViewById(R.id.id_tv_chat_msg);
mItemTvTime = itemView.findViewById(R.id.id_tv_time);
}
}
}
複製代碼
mIdRvContent.setAdapter(new ChatRvAdapter(getMsgBeans()));
mIdRvContent.setLayoutManager(new LinearLayoutManager(this));
複製代碼
newState
:1:開始下滑
---0:手指離開屏幕
---2:手指離開屏幕,但還在滑動
dx
,dy
每次移動的距離post
mIdRvContent.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
ToastUtil.show(V012_QQMsgActivity.this, "newState:" + newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
});
複製代碼