使用RecyclerView实现滑动添加、滑动删除,以及瀑布流、ListView、GridView的转换
来源:互联网 发布:数据库服务器 编辑:程序博客网 时间:2024/05/23 11:09
IDE:AndroidStudio
首先:添加依赖库
compile 'com.android.support:recyclerview-v7:23.4.0'
效果图如下:
说明
RecyclerView.Adapter托管数据集合,为每个Item创建视图RecyclerView.ViewHolder承载Item视图的子视图RecyclerView.LayoutManager负责Item视图的布局RecyclerView.ItemDecoration给Item进行各种装饰DefaultItemAnimator负责添加、删除数据时的动画效果
说明
RecyclerAdapter托管数据集合,为每个Item创建视图CustomViewHolder承载Item视图的子视图CustomCallback负责Item触摸事件CustomItemDecoration用来绘制divider
说明
IOnRecyclerViewItemClickListener实现 RecyclerView的item点击事件IRecyclerViewItemChange实现RecyclerView的 item 改变
布局文件
1. main_activity
<?xml version="1.0" encoding="utf-8"?><!--main_activity--><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TableRow android:layout_width="match_parent" android:layout_height="wrap_content"> <Button android:id="@+id/btn_listViewVer_activity_main" style="?android:attr/buttonBarButtonStyle" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="列表(竖)"/> <Button android:id="@+id/btn_GridViewVer_activity_main" style="?android:attr/buttonBarButtonStyle" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="网格(竖)"/> <Button android:id="@+id/btn_staggeredGridVer_activity_main" style="?android:attr/buttonBarButtonStyle" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="瀑布(竖)"/> </TableRow> <TableRow android:layout_width="match_parent" android:layout_height="wrap_content"> <Button android:id="@+id/btn_listViewHor_activity_main" style="?android:attr/buttonBarButtonStyle" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="列表(横)"/> <Button android:id="@+id/btn_GridViewHor_activity_main" style="?android:attr/buttonBarButtonStyle" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:text="网格(横)"/> <Button android:id="@+id/btn_staggeredGridHor_activity_main" style="?android:attr/buttonBarButtonStyle" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="瀑布(横)"/> </TableRow> <android.support.v7.widget.RecyclerView android:id="@+id/rv_recyclerView_activity_main" android:layout_width="match_parent" android:layout_height="match_parent"/></LinearLayout>
2 . item_recycle_view_activity_main
<?xml version="1.0" encoding="utf-8"?><!--item_recycle_view_activity_main--><TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/tv_name_item_recycler_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:padding="10dp" android:textSize="20sp"/>
代码:
都写在一个类里了 MainActivity.java
import android.graphics.Color;import android.graphics.Rect;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.DefaultItemAnimator;import android.support.v7.widget.GridLayoutManager;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.OrientationHelper;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.StaggeredGridLayoutManager;import android.support.v7.widget.helper.ItemTouchHelper;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.Button;import android.widget.FrameLayout;import android.widget.TextView;import android.widget.Toast;import java.util.ArrayList;import java.util.Collections;import java.util.List;import java.util.Random;/** * 自定义 实现 RecyclerView的item点击事件 回调 */interface IOnRecyclerViewItemClickListener { /** * 点击 * * @param object 数据 */ void onItemClick(Object object); /** * 长按 * * @param object 数据 */ void onItemLongClick(Object object);}/** * 实现RecyclerView的 item 改变 */interface IRecyclerViewItemChange { //添加位于指定位置的前、后 enum EOrientation { FRONT,//前 BEHIND//后 } /** * 调换item位置 * * @param viewHolder 原始位置 * @param target 调换后的位置 */ void moveItem(RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target); /** * 删除目标位置的item * * @param viewHolder 准备删除的item */ void removeItem(RecyclerView.ViewHolder viewHolder); /** * 在指定的位置的添加一个item,并指定在该位置的前面还是后面添加 * * @param viewHolder 指定的item * @param orientation 指定的方向 */ void addItem(RecyclerView.ViewHolder viewHolder, EOrientation orientation);}/** * 实现RecyclerView的左划添加、右划删除、ListView、GridView、瀑布流的转换。 * 使用 RecyclerView ,必须指定一个适配器和一个布局管理器。 * 布局管理器系统提供的有三个,分别是: * LinearLayoutManager 以垂直或水平滚动列表方式显示数据 * GridLayoutManager 在网格中显示数据 * StaggeredGridLayoutManager 在交错网格中显示数据 * 如果要自定义布局管理器,继承 RecyclerView.LayoutManager * 适配器继承RecyclerView.Adapter。 * 自定义item动画 RecyclerView.ItemAnimator, 之后使用RecyclerView.setItemAnimator()方法 */public class MainActivity extends AppCompatActivity implements View.OnClickListener, IOnRecyclerViewItemClickListener { //切换为垂直列表 private Button btn_listViewVer_activity_main; //切换为水平列表 private Button btn_listViewHor_activity_main; //切换为垂直网格 private Button btn_GridViewVer_activity_main; //切换为水平网格 private Button btn_GridViewHor_activity_main; //切换垂直瀑布 private Button btn_staggeredGridVer_activity_main; //切换水平瀑布 private Button btn_staggeredGridHor_activity_main; //recyclerView private RecyclerView rv_recyclerView_activity_main; //默认为垂直正序列表排列 LinearLayoutManager linearLayoutManagerVertical; //设为水平正序列表排列 LinearLayoutManager linearLayoutManagerHorizontal; //设为垂直正序网格排列 GridLayoutManager gridLayoutManagerVertical; //设为水平正序网格排列 GridLayoutManager gridLayoutManagerHorizontal; //设为垂直错开网格排列 StaggeredGridLayoutManager staggeredGridLayoutManagerVertical; //设为垂直错开网格排列 StaggeredGridLayoutManager staggeredGridLayoutManagerHorizontal; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findView(); initLayoutManager(); initData(); } public void findView() { btn_listViewVer_activity_main = (Button) findViewById(R.id.btn_listViewVer_activity_main); btn_listViewHor_activity_main = (Button) findViewById(R.id.btn_listViewHor_activity_main); btn_GridViewVer_activity_main = (Button) findViewById(R.id.btn_GridViewVer_activity_main); btn_GridViewHor_activity_main = (Button) findViewById(R.id.btn_GridViewHor_activity_main); btn_staggeredGridVer_activity_main = (Button)findViewById(R.id.btn_staggeredGridVer_activity_main); btn_staggeredGridHor_activity_main = (Button) findViewById(R.id.btn_staggeredGridHor_activity_main); rv_recyclerView_activity_main = (RecyclerView) findViewById(R.id.rv_recyclerView_activity_main); } public void initLayoutManager() { /* * 默认为垂直正序列表排列 * 等同于new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false); */ linearLayoutManagerVertical = new LinearLayoutManager(this); /* * 设为水平正序列表排列 * 若第三个参数为 true 则为倒序。 */ linearLayoutManagerHorizontal = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false); /* * 设为垂直正序网格排列, 有两列 */ gridLayoutManagerVertical = new GridLayoutManager(this, 2, LinearLayoutManager.VERTICAL, false); /* * 设为水平正序网格排列, 有5行 */ gridLayoutManagerHorizontal = new GridLayoutManager(this, 5, LinearLayoutManager.HORIZONTAL, false); /* * 设为垂直错开网格排列,有两列 */ staggeredGridLayoutManagerVertical = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL); /* * 设为垂直错开网格排列,有5行 */ staggeredGridLayoutManagerHorizontal = new StaggeredGridLayoutManager(5, LinearLayoutManager.HORIZONTAL); } public void initData() { //注册btn监听 btn_listViewVer_activity_main.setOnClickListener(this); btn_listViewHor_activity_main.setOnClickListener(this); btn_GridViewVer_activity_main.setOnClickListener(this); btn_GridViewHor_activity_main.setOnClickListener(this); btn_staggeredGridVer_activity_main.setOnClickListener(this); btn_staggeredGridHor_activity_main.setOnClickListener(this); //初始化适配器所需的数据 List<DataCollection> color = new ArrayList<DataCollection>(); Random random = new Random(); for (int i = 0; i <= 255; ++i) { color.add(new DataCollection(Color.rgb(random.nextInt(256), random.nextInt(256), random.nextInt(256)), (i + ""), 100 + random.nextInt(15) * 10)); } //初始化适配器 RecyclerAdapter recyclerAdapter = new RecyclerAdapter(color, this); //在这里,我们的RecyclerView的大小不受其内容改变,所以可以设为true来优化RecyclerView的加载 rv_recyclerView_activity_main.setHasFixedSize(true); //为RecyclerView设置适配器 rv_recyclerView_activity_main.setAdapter(recyclerAdapter); //设置列表删除和添加时的动画 rv_recyclerView_activity_main.setItemAnimator(new DefaultItemAnimator()); //设置列表每个Item的间隔线 rv_recyclerView_activity_main.addItemDecoration(new CustomItemDecoration(6, 3)); // 设置item监听点击事件 recyclerAdapter.setItemClickListener(this); //设置触摸监听事件 ItemTouchHelper.Callback callback = new CustomCallback(recyclerAdapter); ItemTouchHelper helper = new ItemTouchHelper(callback); helper.attachToRecyclerView(rv_recyclerView_activity_main); } /** * 数据类,用于RecyclerView适配器 */ public class DataCollection { private int color; private String name; private int height; public DataCollection(int color, String name, int height) { this.color = color; this.name = name; this.height = height; } public int getColor() { return this.color; } public String getName() { return this.name; } public int getHeight() { return height; } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_listViewVer_activity_main: rv_recyclerView_activity_main.setLayoutManager(linearLayoutManagerVertical); Toast.makeText(MainActivity.this, "当前为“垂直” 正序“列表”排列", Toast.LENGTH_SHORT).show(); break; case R.id.btn_listViewHor_activity_main: rv_recyclerView_activity_main.setLayoutManager(linearLayoutManagerHorizontal); Toast.makeText(MainActivity.this, "当前为“水平”正序“列表”排列", Toast.LENGTH_SHORT).show(); break; case R.id.btn_GridViewVer_activity_main: rv_recyclerView_activity_main.setLayoutManager(gridLayoutManagerVertical); Toast.makeText(MainActivity.this, "当前为 “垂直” 正序 “网格” 排列", Toast.LENGTH_SHORT).show(); break; case R.id.btn_GridViewHor_activity_main: rv_recyclerView_activity_main.setLayoutManager(gridLayoutManagerHorizontal); Toast.makeText(MainActivity.this, "当前为 “水平” 正序 “网格” 排列", Toast.LENGTH_SHORT).show(); break; case R.id.btn_staggeredGridVer_activity_main: rv_recyclerView_activity_main.setLayoutManager(staggeredGridLayoutManagerVertical); Toast.makeText(MainActivity.this, "当前为 “垂直” 正序 “瀑布” 排列", Toast.LENGTH_SHORT).show(); break; case R.id.btn_staggeredGridHor_activity_main: rv_recyclerView_activity_main.setLayoutManager(staggeredGridLayoutManagerHorizontal); Toast.makeText(MainActivity.this, "当前为 “水平” 正序 “瀑布” 排列", Toast.LENGTH_SHORT).show(); break; } } @Override public void onItemClick(Object object) { Toast.makeText(MainActivity.this, "点击了" + object.toString(), Toast.LENGTH_SHORT).show(); } @Override public void onItemLongClick(Object object) { Toast.makeText(MainActivity.this, "长按了" + object.toString(), Toast.LENGTH_SHORT).show(); } /** * RecyclerAdapter RecyclerView适配器 */ public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.CustomViewHolder> implements IRecyclerViewItemChange { /** * 数据(颜色 和 名字 、高度) */ private List<DataCollection> data; /** * RecyclerView的item点击监听器 */ private IOnRecyclerViewItemClickListener listenerItem; public Runnable runnable = new Runnable() { @Override public void run() { while (true) { } } }; public RecyclerAdapter(List<DataCollection> data, IOnRecyclerViewItemClickListener listenerItem) { this.data = data; this.listenerItem = listenerItem; } public void setItemClickListener(IOnRecyclerViewItemClickListener itemClickListener) { this.listenerItem = itemClickListener; } @Override public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycle_view_activity_main, parent, false); return new CustomViewHolder(view); } @Override public void onBindViewHolder(final CustomViewHolder holder, final int position) { FrameLayout.LayoutParams vLayoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, data.get(position).height); holder.tvItemName.setLayoutParams(vLayoutParams); holder.tvItemName.setText(data.get(position).name); holder.tvItemName.setBackgroundColor(data.get(position).color); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //输出当前被点击item的TextView内容(及position) listenerItem.onItemClick(holder.tvItemName.getText().toString()); } }); holder.tvItemName.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { listenerItem.onItemLongClick(holder.tvItemName.getText().toString()); return true; } }); } @Override public int getItemCount() { return data != null ? data.size() : 0; } /** * 移动 * * @param viewHolder 原始位置 * @param target 调换后的位置 */ @Override public void moveItem(RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { int fromPosition = viewHolder.getAdapterPosition(); int moveToPsoition = target.getAdapterPosition(); //拖动完成后, 对数据进行同步 if ((fromPosition - moveToPsoition) < 0) { for (int i = fromPosition; i < moveToPsoition; ++i) { Collections.swap(data, i, i + 1); } } else { for (int i = fromPosition; i > moveToPsoition; --i) { Collections.swap(data, i, i - 1); } } this.notifyItemMoved(fromPosition, moveToPsoition); } /** * 删除 * * @param viewHolder 准备删除的item */ @Override public void removeItem(RecyclerView.ViewHolder viewHolder) { int position = viewHolder.getAdapterPosition(); data.remove(position); this.notifyItemRemoved(position); CustomViewHolder customViewHolder = (CustomViewHolder) viewHolder; Toast.makeText(getApplicationContext(), "删除了" + customViewHolder.tvItemName.getText().toString(), Toast.LENGTH_SHORT).show(); } /** * 添加 * * @param viewHolder 指定的item * @param orientation 指定的方向 */ @Override public void addItem(RecyclerView.ViewHolder viewHolder, EOrientation orientation) { int position = viewHolder.getAdapterPosition(); CustomViewHolder customViewHolder = (CustomViewHolder) viewHolder; switch (orientation) { case FRONT: data.add(position - 1, data.get(position)); //插入 this.notifyItemInserted(position - 1); //刷新 添加的位置里的item this.notifyItemChanged(position); break; case BEHIND: data.add(position + 1, data.get(position)); //插入 this.notifyItemInserted(position); //刷新 添加的位置里的item this.notifyItemChanged(position + 1); break; } Toast.makeText(getApplication(), "添加了" + customViewHolder.tvItemName.getText().toString(), Toast.LENGTH_SHORT).show(); } /** * 实现 RecyclerView的 ViewHolder */ public class CustomViewHolder extends RecyclerView.ViewHolder { private TextView tvItemName; public CustomViewHolder(View itemView) { super(itemView); tvItemName = (TextView) itemView.findViewById(R.id.tv_name_item_recycler_view); } } } /** * 负责Item触摸事件 */ public class CustomCallback extends ItemTouchHelper.Callback { //适配器对象 private RecyclerAdapter recyclerAdapter; public CustomCallback(RecyclerAdapter adapter) { this.recyclerAdapter = adapter; } /** * 指定可以支持的拖放和滑动的方向 * * @return 返回flag */ @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { //默认上下拖动 int FlagOne = ItemTouchHelper.DOWN | ItemTouchHelper.UP; //默认左右滑动 int FlagTwo = ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT; //获取布局管理器 RecyclerView.LayoutManager rLayoutManager = recyclerView.getLayoutManager(); //如果RecyclerView是水平滚动,设置为上下滑动,左右拖动 if (rLayoutManager.canScrollHorizontally()) { //修改为左右拖动 FlagOne = ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT; //修改为上下滑动 FlagTwo = ItemTouchHelper.DOWN | ItemTouchHelper.UP; } /* 返回的flag 注:第一个参数为拖动(drag)这里“上下左右”都可以拖动, 第二个参数为滑动(swipe) 这里默认是左右可以滑动,若判断是水平滚动,则上下滑动。 */ return makeMovementFlags(FlagOne | FlagTwo, FlagTwo); } //是否允许滑动(默认为true) @Override public boolean isItemViewSwipeEnabled() { return true; } //是否允许拖动(默认为true) @Override public boolean isLongPressDragEnabled() { return true; } /** * 长按拖动的主要方法 * * @return */ @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { //更换RecyclerView中两个对象的在数据的位置 recyclerAdapter.moveItem(viewHolder, target); //返回true表示位置已经更改 return true; } @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { //“上滑”、“右滑”是删除 if (direction == ItemTouchHelper.RIGHT || direction == ItemTouchHelper.UP) { recyclerAdapter.removeItem(viewHolder); } //“左滑”、“下滑”是添加 if (direction == ItemTouchHelper.LEFT || direction == ItemTouchHelper.DOWN) { recyclerAdapter.addItem(viewHolder, IRecyclerViewItemChange.EOrientation.BEHIND); } } } public class CustomItemDecoration extends RecyclerView.ItemDecoration { private int height, width; public CustomItemDecoration(int width, int height) { this.width = width; this.height = height; } /** * @param outRect 控制每个Item的左、上、右、下 的间隔 * @param view * @param parent * @param state */ @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { RecyclerView.LayoutManager rLayoutManager = parent.getLayoutManager(); int position = parent.getChildAdapterPosition(view); if (rLayoutManager instanceof GridLayoutManager) { if (((GridLayoutManager) rLayoutManager).getOrientation() == OrientationHelper.VERTICAL) { int spanCount = ((GridLayoutManager) rLayoutManager).getSpanCount(); outRect.set(position % spanCount == 0 ? 0 : width, 0, (position + 1) % spanCount == 0 ? 0 : width / 2, height); } } else if (rLayoutManager instanceof StaggeredGridLayoutManager) { if (((StaggeredGridLayoutManager) rLayoutManager).getOrientation() == OrientationHelper.VERTICAL) { outRect.set(0, 0, width, height); } else { outRect.set(0, 0, 0, height); } } else { outRect.set(0, 0, 0, height); } } }}
如有错误还请指正,谢谢。
0 0
- 使用RecyclerView实现滑动添加、滑动删除,以及瀑布流、ListView、GridView的转换
- 使用RecyclerView实现ListView,GridView的效果(上下,左右滑动),拖拽与滑动删除
- RecyclerView--实现 ListView,GridView,瀑布流 效果
- RecyclerView实现ListView、GridView、瀑布流
- RecyclerView的滑动删除以及下拉加载
- RecyclerView实现瀑布流,快速滑动,侧滑删除,点击图片放大等效果
- RecyclerView 滑动删除与拖动的实现
- ListView,GridView,RecyclerView滑动错位的终极解决办法
- Android控件RecyclerView实现横向滑动、瀑布流。
- 实现listView滑动删除
- 精通RecyclerView:打造ListView、GridView、瀑布流;学会添加分割线、 添加删除动画 、Item点击事件
- 基于ListView的滑动删除、添加、修改
- Android中Recyclerview使用1----实现ListView,GridView,瀑布流样式
- 关于RecyclerView实现瀑布流,上下滑动时item之间互换位置的问题
- 关于RecyclerView实现瀑布流,上下滑动时item之间互换位置的问题
- ListView的滑动删除
- listview的滑动删除
- listview的滑动删除
- protobuf传输文件
- 由 12306.cn 谈谈高并发+高负载网站性能技术
- Swift - 加速传感器(CoreMotion)的用法,小球加速运动并反弹样例
- windows下安装rabbitmq的php扩展amqp
- bootstrapTable跨域问题
- 使用RecyclerView实现滑动添加、滑动删除,以及瀑布流、ListView、GridView的转换
- 图结构练习——BFS——从起始点到目标点的最短步数
- 10、RedHat6 仲裁盘
- Linux开发环境搭建之Samba服务器配置
- textfiled值得拥有
- 例解 autoconf 和 automake 生成 Makefile 文件
- 如何将一个项目导出成API文档
- ACPI 主要Table作用
- 前端后台异常