碼雲鏈接,歡迎clone
史上最全recycleView 集合,下拉刷新+上拉加載+左滑刪除+點擊按鈕滑動到指定位置
最近項目需求,需要使用viewpager+fragment,同時還有類似支付寶的滑動到指定位置需求,另外還有點擊頂部button,使recycleView滑動到指定位置,簡直是把我這個老黃牛給累死了,好在萬能的百度,給了我指引。於是我這個搬磚工,把網上現在的東西組合了下,有了今天的成果。話不多說,上效果圖
主要思路
- 使用viewpager+tablelqyout,這個沒啥好說的,現在比較流行的多頁面框架
- 下拉刷新,上拉加載,這個使用了git上非常著名的smartRefreshLayout,不過話說回來,自從用了這個框架,一句話:誰用誰知道!
- 左滑菜單,這個網上實現的也非常多,但是很可惜,像easySwipterLayout,還有其它的一些實現方式都是在recycleView上實現,這樣造成了與recycleView代碼混合在一起,非常不利於現在的少侵入式框架,最終發現有一個WeSwipe,可以實現與recycleView的最少侵入。於是就選擇了這款左滑框架。
關鍵代碼
- recycleView設置關鍵代碼 ,其中有上拉刷新,下拉加載,還有滑動的監聽,在滑動監聽中找到當前屏幕可見的第一條item的position,其中下面的代碼 是關鍵
LinearLayoutManager ll = (LinearLayoutManager) recyclerView.getLayoutManager();
int firstItem = ll.findFirstVisibleItemPosition();
//下拉刷新設置
refreshLayout.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh(@NonNull RefreshLayout refreshLayout) {
refreshLayout.finishRefresh(2000);
}
});
//上拉加載設置
refreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() {
@Override
public void onLoadMore(@NonNull RefreshLayout refreshLayout) {
refreshLayout.finishLoadMore(2000);
}
});
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
mAdapter.setDelectedItemListener(new WorkAdapter.DeletedItemListener() {
@Override
public void deleted(int position) {
dataList.remove(position);
mAdapter.notifyItemRemoved(position);
}
});
recyclerView.setAdapter(mAdapter);
WeSwipe.attach(recyclerView);
// recycleView滾動需要的類
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (mShouldScroll && RecyclerView.SCROLL_STATE_IDLE == newState) {
mShouldScroll = false;
smoothMoveToPosition(recyclerView, mToPosition);
} else if (newState == RecyclerView.SCROLL_STATE_IDLE) {
//滑動終止
settabbarTop();
}
}
});
/**
* 滑動到指定位置
*/
private void smoothMoveToPosition(RecyclerView mRecyclerView, final int position) {
// 第一個可見位置
int firstItem = mRecyclerView.getChildLayoutPosition(mRecyclerView.getChildAt(0));
// 最後一個可見位置
int lastItem = mRecyclerView.getChildLayoutPosition(mRecyclerView.getChildAt(mRecyclerView.getChildCount() - 1));
if (position < firstItem) {
// 第一種可能:跳轉位置在第一個可見位置之前,使用smoothScrollToPosition
mRecyclerView.smoothScrollToPosition(position);
} else if (position <= lastItem) {
// 第二種可能:跳轉位置在第一個可見位置之後,最後一個可見項之前
int movePosition = position - firstItem;
if (movePosition >= 0 && movePosition < mRecyclerView.getChildCount()) {
int top = mRecyclerView.getChildAt(movePosition).getTop();
// smoothScrollToPosition 不會有效果,此時調用smoothScrollBy來滑動到指定位置
mRecyclerView.smoothScrollBy(0, top);
}
} else {
// 第三種可能:跳轉位置在最後可見項之後,則先調用smoothScrollToPosition將要跳轉的位置滾動到可見位置
// 再通過onScrollStateChanged控制再次調用smoothMoveToPosition,執行上一個判斷中的方法
mRecyclerView.smoothScrollToPosition(position);
mToPosition = position;
mShouldScroll = true;
}
}
adapter關鍵代碼,使用weSwip左滑菜單 ,必須實現WeSwipeHelper.SwipeLayoutTypeCallBack,這裏有三個關鍵方法
解釋如下:
- getSwipeWidth 方法是指定可左滑動的距離
- needSwipeLayout 方法是右滑的菜單view
- onScreenView 返回的是contentView,即全屏的view
@Override
public float getSwipeWidth() {
//佈局隱藏超過父佈局的範圍的時候這裏得不到寬度
return dip2px(context, 240);
}
@Override
public View needSwipeLayout() {
return slideItem;
}
@Override
public View onScreenView() {
return textView;
}
package cn.ttxs.wq.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
import cn.ttxs.wq.R;
import cn.we.swipe.helper.WeSwipeHelper;
/**
* Created by WANG on 18/4/24.
*/
public class WorkAdapter extends RecyclerView.Adapter<WorkAdapter.RecViewholder> {
private Context context;
private List<String> dataList = new ArrayList<>();
private LayoutInflater layoutInflater;
DeletedItemListener delectedItemListener;
public void setDelectedItemListener(DeletedItemListener deletedItemListener) {
this.delectedItemListener = deletedItemListener;
}
public WorkAdapter(Context context, List<String> dataList) {
this.context = context;
this.dataList = dataList;
layoutInflater = LayoutInflater.from(context);
}
public void setList(List<String> list) {
dataList.clear();
dataList.addAll(list);
notifyItemMoved(0, dataList.size() - 1);
}
public List<String> getDataList() {
return dataList;
}
public void removeDataByPosition(int position) {
if (position >= 0 && position < dataList.size()) {
dataList.remove(position);
notifyItemRemoved(position);
}
}
@Override
public RecViewholder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = layoutInflater.inflate(R.layout.layout_item_twotype, parent, false);
return new RecViewholder(view);
}
@Override
public void onBindViewHolder(final RecViewholder holder, int position) {
holder.textView.setText(dataList.get(holder.getAdapterPosition()));
holder.textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, "s " + holder.getAdapterPosition(), Toast.LENGTH_SHORT).show();
}
});
holder.zhiding.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, "置頂" + holder.getAdapterPosition(), Toast.LENGTH_SHORT).show();
}
});
holder.yidu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, "已讀" + holder.getAdapterPosition(), Toast.LENGTH_SHORT).show();
}
});
holder.shanchu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != delectedItemListener) {
delectedItemListener.deleted(holder.getAdapterPosition());
}
}
});
}
@Override
public int getItemCount() {
return dataList.size();
}
/**
* view.getWidth()獲取的是屏幕中可以看到的大小.
*/
public class RecViewholder extends RecyclerView.ViewHolder implements WeSwipeHelper.SwipeLayoutTypeCallBack {
public TextView textView;
public LinearLayout slide;
public TextView zhiding, yidu, shanchu;
public RelativeLayout slideItem;
public RecViewholder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.item_text);
zhiding = itemView.findViewById(R.id.tv_totop);
yidu = itemView.findViewById(R.id.tv_read);
shanchu = itemView.findViewById(R.id.tv_del);
slide = itemView.findViewById(R.id.slide);
slideItem = itemView.findViewById(R.id.slide_itemView);
}
@Override
public float getSwipeWidth() {
//佈局隱藏超過父佈局的範圍的時候這裏得不到寬度
return dip2px(context, 240);
}
@Override
public View needSwipeLayout() {
return slideItem;
}
@Override
public View onScreenView() {
return textView;
}
}
/**
* 根據手機分辨率從DP轉成PX
*
* @param context
* @param dpValue
* @return
*/
public static int dip2px(Context context, float dpValue) {
float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
public interface DeletedItemListener {
void deleted(int position);
}
}
recycleView使用的layout文件關鍵代碼
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginBottom="1dp"
android:clipChildren="false">
<RelativeLayout
android:id="@+id/slide_itemView"
android:clipChildren="false"
android:tag="slide_flag"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/item_text"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#e1e1e1"
android:gravity="center"
android:text="item"
android:textColor="#333333"
android:textSize="16sp" />
<LinearLayout
android:id="@+id/slide"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="@id/item_text"
android:clipChildren="false"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_totop"
android:layout_width="80dp"
android:layout_height="match_parent"
android:background="#C8C7CD"
android:gravity="center"
android:text="置頂"
android:textColor="#ffffff" />
<TextView
android:id="@+id/tv_read"
android:layout_width="80dp"
android:layout_height="match_parent"
android:background="#FF9D00"
android:gravity="center"
android:text="設爲已讀"
android:textColor="#ffffff" />
<TextView
android:id="@+id/tv_del"
android:layout_width="80dp"
android:layout_height="match_parent"
android:background="#FE3C31"
android:gravity="center"
android:text="刪除"
android:textColor="#ffffff" />
</LinearLayout>
</RelativeLayout>
</RelativeLayout>