热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

RecyclerView实现拖拽排序效果

这篇文章主要为大家详细介绍了RecyclerView实现拖拽排序效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

效果就是这样,RecyclerView列表可拖拽排序,可删除,可添加;

RecyclerView给我们提供了一个手势器:

ItemTouchHelper helper = new ItemTouchHelper(new ItemTouchHelper.Callback() { 
  @Override 
  public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { 
   int dragFrlg = 0; 
   if (recyclerView.getLayoutManager() instanceof GridLayoutManager){ 
    dragFrlg = ItemTouchHelper.UP|ItemTouchHelper.DOWN|ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT; 
   }else if(recyclerView.getLayoutManager() instanceof LinearLayoutManager){ 
    dragFrlg = ItemTouchHelper.UP|ItemTouchHelper.DOWN; 
   } 
   return makeMovementFlags(dragFrlg,0); 
  } 
 
  @Override 
  public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { 
   //滑动事件 下面注释的代码,滑动后数据和条目错乱,被舍弃 
//   Collections.swap(datas,viewHolder.getAdapterPosition(),target.getAdapterPosition()); 
//   ap.notifyItemMoved(viewHolder.getAdapterPosition(),target.getAdapterPosition()); 
 
   //得到当拖拽的viewHolder的Position 
   int fromPosition = viewHolder.getAdapterPosition(); 
   //拿到当前拖拽到的item的viewHolder 
   int toPosition = target.getAdapterPosition(); 
   if (fromPosition  toPosition; i--) { 
     Collections.swap(datas, i, i - 1); 
    } 
   } 
   ap.notifyItemMoved(fromPosition, toPosition); 
   return true; 
  } 
 
  @Override 
  public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { 
    //侧滑删除可以使用; 
  } 
 
  @Override 
  public boolean isLongPressDragEnabled() { 
   return true; 
  } 
  /** 
   * 长按选中Item的时候开始调用 
   * 长按高亮 
   * @param viewHolder 
   * @param actionState 
   */ 
  @Override 
  public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { 
   if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) { 
    viewHolder.itemView.setBackgroundColor(Color.RED); 
    //获取系统震动服务//震动70毫秒 
    Vibrator vib = (Vibrator) getSystemService(Service.VIBRATOR_SERVICE); 
    vib.vibrate(70); 
   } 
   super.onSelectedChanged(viewHolder, actionState); 
  } 
 
  /** 
   * 手指松开的时候还原高亮 
   * @param recyclerView 
   * @param viewHolder 
   */ 
  @Override 
  public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { 
   super.clearView(recyclerView, viewHolder); 
   viewHolder.itemView.setBackgroundColor(0); 
   ap.notifyDataSetChanged(); //完成拖动后刷新适配器,这样拖动后删除就不会错乱 
  } 
 }); 

设置给RecyclerView即可:

helper.attachToRecyclerView(rv); 

下面是完整的代码和Xml布局文件:

public class MainActivity extends AppCompatActivity implements View.OnClickListener { 
 private final String TAG = this.getClass().getSimpleName(); 
 private List d = Arrays.asList( 
   "A","B","C","D","E","F","G" 
   ,"H","I","J","K","L","M","N" 
   ,"O","P","Q","R","S","T" 
   ,"U","V","W","X","Y","Z"); 
 private RecyclerView rv ; 
 private Ap ap; 
 private List datas; 
 private EditText edAdd; 
 
 @Override 
 protected void onCreate(Bundle savedInstanceState) { 
  super.onCreate(savedInstanceState); 
  setContentView(R.layout.activity_main); 
  initData(); 
  rv = findViewById(R.id.rv); 
  edAdd =findViewById(R.id.et_add); 
  rv.setLayoutManager(new GridLayoutManager(this,3)); 
//  rv.setLayoutManager(new LinearLayoutManager(this)); 
  ap = new Ap(this, datas); 
  rv.setAdapter(ap); 
  helper.attachToRecyclerView(rv); 
  findViewById(R.id.tv).setOnClickListener(this); 
  findViewById(R.id.tv_add).setOnClickListener(this); 
 } 
 
 private void initData() { 
  datas = new ArrayList<>(); 
//  直接用d操作集合会崩溃,Arrays.asList集合不可增删改;详细可以看我的博客 
  for (int i = 0; i  extends RecyclerView.Adapter{ 
  private Context context; 
  public List stringList; 
  public Ap(Context context, List stringList) { 
   this.cOntext= context; 
   this.stringList = stringList; 
  } 
 
  @Override 
  public Ap.Vh onCreateViewHolder(ViewGroup parent, int viewType) { 
   return new Vh(LayoutInflater.from(context).inflate(R.layout.item_rv,null)); 
  } 
 
  @Override 
  public void onBindViewHolder(Ap.Vh holder, final int position) { 
   holder.tv.setText(stringList.get(position).toString()); 
   holder.iv.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View view) { 
     remove(position); 
    } 
   }); 
  } 
 
  @Override 
  public int getItemCount() { 
   return stringList.size(); 
  } 
 
  public void add(T item){ 
   int position = stringList.size(); 
   stringList.add(item); 
   notifyItemInserted(position); 
  } 
 
  public void add(int position,T item){ 
   stringList.add(position,item); 
   notifyItemInserted(position); 
  } 
//  public void remove(T item) { 
//   final int position = stringList.indexOf(item); 
//   if (-1 == position) 
//    return; 
//   stringList.remove(item); 
//   notifyItemRemoved(position); 
//  } 
 
  public void remove(int position) { 
   stringList.remove(position); 
   notifyItemRemoved(position); 
   notifyItemRangeChanged(position,stringList.size()); 
  } 
 
  class Vh extends RecyclerView.ViewHolder { 
 
   public Vh(View itemView) { 
    super(itemView); 
    tv = itemView.findViewById(R.id.tv); 
    iv = itemView.findViewById(R.id.iv_delete); 
   } 
   public TextView tv; 
   public ImageView iv; 
  } 
 } 

 ItemTouchHelper helper = new ItemTouchHelper(new ItemTouchHelper.Callback() { 
  @Override 
  public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { 
   int dragFrlg = 0; 
   if (recyclerView.getLayoutManager() instanceof GridLayoutManager){ 
    dragFrlg = ItemTouchHelper.UP|ItemTouchHelper.DOWN|ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT; 
   }else if(recyclerView.getLayoutManager() instanceof LinearLayoutManager){ 
    dragFrlg = ItemTouchHelper.UP|ItemTouchHelper.DOWN; 
   } 
   return makeMovementFlags(dragFrlg,0); 
  } 
 
  @Override 
  public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { 
   //滑动事件 下面注释的代码,滑动后数据和条目错乱,被舍弃 
//   Collections.swap(datas,viewHolder.getAdapterPosition(),target.getAdapterPosition()); 
//   ap.notifyItemMoved(viewHolder.getAdapterPosition(),target.getAdapterPosition()); 
 
   //得到当拖拽的viewHolder的Position 
   int fromPosition = viewHolder.getAdapterPosition(); 
   //拿到当前拖拽到的item的viewHolder 
   int toPosition = target.getAdapterPosition(); 
   if (fromPosition  toPosition; i--) { 
     Collections.swap(datas, i, i - 1); 
    } 
   } 
   ap.notifyItemMoved(fromPosition, toPosition); 
   return true; 
  } 
 
  @Override 
  public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { 
    //侧滑删除可以使用; 
  } 
 
  @Override 
  public boolean isLongPressDragEnabled() { 
   return true; 
  } 
  /** 
   * 长按选中Item的时候开始调用 
   * 长按高亮 
   * @param viewHolder 
   * @param actionState 
   */ 
  @Override 
  public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { 
   if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) { 
    viewHolder.itemView.setBackgroundColor(Color.RED); 
    //获取系统震动服务//震动70毫秒 
    Vibrator vib = (Vibrator) getSystemService(Service.VIBRATOR_SERVICE); 
    vib.vibrate(70); 
   } 
   super.onSelectedChanged(viewHolder, actionState); 
  } 
 
  /** 
   * 手指松开的时候还原高亮 
   * @param recyclerView 
   * @param viewHolder 
   */ 
  @Override 
  public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { 
   super.clearView(recyclerView, viewHolder); 
   viewHolder.itemView.setBackgroundColor(0); 
   ap.notifyDataSetChanged(); //完成拖动后刷新适配器,这样拖动后删除就不会错乱 
  } 
 }); 
} 

Xml布局文件:

<&#63;xml version="1.0" encoding="utf-8"&#63;> 
 
 
  
   
   
   
  
  
 
 

RecyclerView的Item:

<&#63;xml version="1.0" encoding="utf-8"&#63;> 
 
  
  
 
  
  
 

资源链接Github

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • Android LED 数字字体的应用与实现
    本文介绍了一种适用于 Android 应用的 LED 数字字体(digital font),并详细描述了其在 UI 设计中的应用场景及其实现方法。这种字体常用于视频、广告倒计时等场景,能够增强视觉效果。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 解决微信电脑版无法刷朋友圈问题:使用安卓远程投屏方案
    在工作期间想要浏览微信和朋友圈却不太方便?虽然微信电脑版目前不支持直接刷朋友圈,但通过远程投屏技术,可以轻松实现在电脑上操作安卓设备的功能。 ... [详细]
  • 本文详细介绍了 Java 中 org.apache.xmlbeans.SchemaType 类的 getBaseEnumType() 方法,提供了多个代码示例,并解释了其在不同场景下的使用方法。 ... [详细]
  • 本文深入探讨了 com.example.android.sunshine.data.TestUtilities 中 validateThenCloseCursor() 方法的使用方法及其代码示例,旨在帮助开发者更好地理解和应用该方法。 ... [详细]
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
  • 本文详细介绍了如何使用 Yii2 的 GridView 组件在列表页面实现数据的直接编辑功能。通过具体的代码示例和步骤,帮助开发者快速掌握这一实用技巧。 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 本文介绍如何使用 Sortable.js 库实现元素的拖拽和位置交换功能。Sortable.js 是一个轻量级、无依赖的 JavaScript 库,支持拖拽排序、动画效果和多种插件扩展。通过简单的配置和事件处理,可以轻松实现复杂的功能。 ... [详细]
  • 探讨一个显示数字的故障计算器,它支持两种操作:将当前数字乘以2或减去1。本文将详细介绍如何用最少的操作次数将初始值X转换为目标值Y。 ... [详细]
  • 本文详细探讨了在Android 8.0设备上使用ChinaCock的TCCBarcodeScanner进行扫码时出现的应用闪退问题,并提供了解决方案。通过调整配置文件,可以有效避免这一问题。 ... [详细]
  • 本章将深入探讨移动 UI 设计的核心原则,帮助开发者构建简洁、高效且用户友好的界面。通过学习设计规则和用户体验优化技巧,您将能够创建出既美观又实用的移动应用。 ... [详细]
  • 本文介绍如何在应用程序中使用文本输入框创建密码输入框,并通过设置掩码来隐藏用户输入的内容。我们将详细解释代码实现,并提供专业的补充说明。 ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
author-avatar
手机用户2502885897
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有