简单的recycleView 使用
首先写一个简单的RecycleView:首先是MainActivity
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
MyAdapter myAdapter ;
ArrayList<String> arrayList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.rv);
//这里完全可以换成LinearLayoutManager 只是个人demo这样写了。
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 1);
myAdapter = new MyAdapter(this);
recyclerView.setLayoutManager(gridLayoutManager);
//修改默认的动画,不是重点
DefaultItemAnimator defaultItemAnimator = new DefaultItemAnimator();
defaultItemAnimator.setAddDuration(1000);
recyclerView.setItemAnimator(defaultItemAnimator);
recyclerView.setAdapter(myAdapter);
initData();
}
private void initData(){
for(int a = 0; a < 20; a ++){
arrayList.add("demo"+"==="+a);
}
myAdapter.setData(arrayList);
}
}
其次是adapter:
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@NonNull
Context mContext;
ArrayList<String> data = null;
public MyAdapter(@NonNull Context mContext) {
this.mContext = mContext;
}
public void setData(ArrayList<String> data){
this.data = data;
notifyDataSetChanged();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(mContext).inflate(R.layout.recycleview_item,viewGroup,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, final int i) {
((ViewHolder)viewHolder).tv.setText(data.get(i));
}
@Override
public int getItemCount() {
return data==null?0:data.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView tv ;
LinearLayout ll;
public ViewHolder(@NonNull View itemView) {
super(itemView);
tv = itemView.findViewById(R.id.tv);
ll = itemView.findViewById(R.id.ll);
}
}
运行跑起来就是我们一般见到的简单的列表 如图1:
图1.png
这是简单的使用,假如做为展示的列表这样就可以完成了。但是有时候做成菜单,也就说个数有限。item的顺序可以由用户自己排序,删除。那么就要稍微加点东西了。下面看一下这个文章的主角ItemTouchHelper这里先贴出写好的类然后再分析吧。RecycleViewHelper:
public class RecycleViewHelp {
String TAG = "RecycleViewHelp";
MyAdapter myAdapter;
//绑定Adapter 方便调用adapter里面的方法 其实这边也可以用接口实现。
public RecycleViewHelp(MyAdapter myAdapter) {
this.myAdapter = myAdapter;
}
//这个是主角
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
int swipeFlag = ItemTouchHelper.START|ItemTouchHelper.END;
int drawFlag = ItemTouchHelper.RIGHT|1|2|4;
/** 这个是可以滑动的标志 第一个是长按换位置,第二个是滑动删除 上面的两个int 代表的是滑动的 方向,开源码看一下
源码中是这么定义的
public static final int UP = 1;
public static final int DOWN = 1 << 1;
public static final int LEFT = 1 << 2;
public static final int RIGHT = 1 << 3;
分别代表了上下左右。看源码的时候会发现写代码的会经常用a<<b这种来代表int 上面那个就算
是比较经典的了,我们会用int计算机喜欢用byte 一个byte可以用16进制来表示,用2进制来表示
就是 0000 0000 我们的UP 就是1 计算机中表示就直接是 0000 0001 十进制就是1 然后Down 左
移1 就是0000 0010 十进制2 后面的以此类推 4,8。就是我上面直接写|2|4|1的原因。但是为什么
要用|来把这些联系起来呢 这里揣测一下 设计者的想法 因为|了之后 哪位存在哪位就会变成1 高位
0000不变 低位要向左还是向右就直接变成1 我上面的也就是全变成了1 drawFlag用byte就是
0000 1111 这样很容易看出来 也方便计算,这里只是多写了一些关于源码的想法。
**/
//滑动删除给的是0 代表这次不支持滑动删除方向
return makeMovementFlags(drawFlag, 0);
}
@Override
public boolean isItemViewSwipeEnabled() {
//这个返回代表可以滑动删除。false 代表不可以。
return true ;
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
//这个代表的就是滑动的过程。viewHolder.getAdapterPosition()代表开始要换的,
// target.getAdapterPosition()代表被换到的位置。
//这个要调用adapter的move 方法 这是自己写的 目的是把数据源换掉,位置换掉了,adapter里面
//的数据还是以前的岂不是没有任何意义。
myAdapter.move(viewHolder.getAdapterPosition(),target.getAdapterPosition());
//调用adpater 中的换位置方法也就是我们简单的UI 上的换。
myAdapter.notifyItemMoved(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return true;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
// 这个是删除的时候 调用的方法
Log.d(TAG, "onSwiped: ");
}
@Override
public boolean isLongPressDragEnabled() {
Log.d(TAG, "isLongPressDragEnabled: ");
//这个是否长按支持对item 进行操作。不能拖着就换item吧,要点击一会让他进入可以换位置的状态。
return super.isLongPressDragEnabled();
}
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
Log.d(TAG, "onSelectedChanged: "+actionState);
//这个返回item的状态 是换位置 还是滑动删除 还是结束操作 actionState的参数为 0 1 2
super.onSelectedChanged(viewHolder, actionState);
}
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
Log.d(TAG, "clearView: ");
//这个就是item 操作停止之后的操作。在move 的时候把数据跟位置换掉了 ,这里刷新一下数据源
// 就ok了,不要在move的时候刷新 那会导致滑起的item 回到之前的位置
myAdapter.notifyDataSetChanged();
super.clearView(recyclerView, viewHolder);
}
});
//这个是绑定recycleView 。
public void attacthRecycle(RecyclerView rv){
itemTouchHelper.attachToRecyclerView(rv);
}
}
MainActivity中添加代码:
RecycleViewHelp recycleViewHelp = new RecycleViewHelp(myAdapter);
recycleViewHelp.attacthRecycle(recyclerView);
Adapter中添加代码:
public void move(int start ,int end){
Collections.swap(data, start, end);
}
运行启动。
换位置.gif
至于滑动删除也同理,先改数据源再去刷新适配器。删除,增加 都是有系统提供的方法
data.remove(position)
notifyDataSetChanged();
最后给上自己做的小例子,一般的菜单栏。git:https://github.com/w171066813/RecycleView
类似菜单的RecycleView.gif