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

Android使用CardView作为RecyclerView的Item并实现拖拽和左滑删除

这篇文章主要介绍了Android使用CardView作为RecyclerView的Item并实现拖拽和左滑删除,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

引言

CardView是Android 5.0系统之后引入的众多控件之一,实现之后的效果也是比较酷的,它经常被用在RecyclerView和ListView中的Item中。今天我们就来了解一下CardView的属性,然后使用CardView和RecyclerView结合实现一个可以拖拽Item的布局。

CardView的属性

 CardView继承自FrameLayout,所以子控件的布局规则和FrameLayout的一样,是按照层次堆叠的

下面是CardView的一些常用属性:

CardView的基本使用

先看一下效果:

这是一个CardView,多个罗列起来看起啦会更酷,好了,我们先看一下代码:

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

 
  
    
      
      
      
        
        
        
        
      
    
  

看完了布局文件,是不是觉得这个布局不仅炫酷而且使用简单,下面我们把它应用到RecyclerView中,看起来会更炫酷。

CardView应用在RecyclerView中

CardView通常会应用在RecyclerView和ListView中,今天我们就讲一讲如何应用在RecyclerView中。我们现在在大多数应用或者手机系统界面中会见到这样的效果:

是不是觉得很棒,下面我们就用CardView和RecyclerView来实现一下这个效果。

布局文件

我们实现这个效果的第一步是先添加依赖库:

implementation 'com.android.support:recyclerview-v7:26.+'
implementation 'com.android.support:cardview-v7:26.+'

然后写一下布局文件,Item的布局文件我就直接采用上面的代码了,然后再写一个主界面的布局文件,比较简单,如下:

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

 
  
 

Activity内代码

public class MainActivity extends AppCompatActivity {
  private RecyclerView mRecyclerView;
 
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
 
    mRecyclerView = (RecyclerView) findViewById(R.id.my_recyclerView);
    //设置LayoutManager
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
    linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
    mRecyclerView.setLayoutManager(linearLayoutManager);
 
    //绑定adapter
    MyAdapter myAdapter = new MyAdapter(this);
    mRecyclerView.setAdapter(myAdapter);  
 
  }
  //adapter
  class MyAdapter extends RecyclerView.Adapter {
 
    LayoutInflater mInflater;
    List mList = addData();
 
    public MyAdapter(Context context) {
      mInflater = LayoutInflater.from(context);
    }
 
    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
      View view = mInflater.inflate(R.layout.item_my_recyclerview,parent,false);
      ViewHolder viewHolder = new ViewHolder(view);
      return viewHolder;
    }
 
    @Override
    public void onBindViewHolder(MyAdapter.ViewHolder holder, int position) {
      holder.mName.setText(mList.get(position).getUserName());
      holder.mDescribe.setText(mList.get(position).getDescription());
    }
 
    @Override
    public int getItemCount() {
      return mList.size();
    }
 
    public class ViewHolder extends RecyclerView.ViewHolder {
      private TextView mName;
      private TextView mDescribe;
      public ViewHolder(View itemView) {
        super(itemView);
        mName = itemView.findViewById(R.id.txt_name);
        mDescribe = itemView.findViewById(R.id.txt_describe);
      }
    }
  }
  //制造一个数据源
  private class MData{
    String userName;
    String description;
 
    public String getUserName() {
      return userName;
    }
 
    public void setUserName(String userName) {
      this.userName = userName;
    }
 
    public String getDescription() {
      return description;
    }
 
    public void setDescription(String description) {
      this.description = description;
    }
  }
  private List addData(){
    List list = new ArrayList();
 
    MData mData = new MData();
    mData.setUserName("王二");
    mData.setDescription("一个很厉害的人");
    list.add(mData);
 
    mData = new MData();
    mData.setUserName("张三");
    mData.setDescription("呵呵");
    list.add(mData);
 
    mData = new MData();
    mData.setUserName("李四");
    mData.setDescription("嘻嘻");
    list.add(mData);
 
    mData = new MData();
    mData.setUserName("赵一");
    mData.setDescription("呵呵");
    list.add(mData);
 
    mData = new MData();
    mData.setUserName("钱多");
    mData.setDescription("地主家的傻儿子");
    list.add(mData);
    return list;
  }
}

好了,这就是一个没有任何效果的列表界面,我一看一下效果:

ItemTouchHelper

想实现拖拽和滑动删除的效果,很可惜RecyclerView并没有提供现成的API供我们使用,但是SDK为我们提供了ItemTouchHelper这样一个工具类帮助我们来轻松实现这些功能,我们先来了解一下ItemTouchHelper。官方文档是这样介绍的:

This is a utility class to add swipe to dismiss and drag & drop support to RecyclerView.It works with a RecyclerView and a Callback class, which configures what type of interactions are enabled and also receives events when user performs these actions.Depending on which functionality you support, you should override onMove(RecyclerView, ViewHolder, ViewHolder) and / or onSwiped(ViewHolder, int).

大致意思就是,这是个工具类,可以实拖拽移动和策划删除,使用这个工具需要RecyclerView和Callback。同时需要重写onMove()和onSwiped()方法。接下来就讲讲如何使用ItemTouchHlper。

1.新建一个接口,并且让Adapter实现

我们选择使用一个接口来实现Adapter和ItemTouchHelper之间涉及数据的操作,因为ItemTouchHelper完成触摸的各种动画以后,就要对Adapter的数据进行操作,比如我们在侧滑删除以后,最后需要调用Adapter的notifyItemRemove()方法来移除该数据。所以我们可以把数据操作的部分抽象成一个接口方法,让Callbac调用它即可。具体如下:

新建一个接口:

ItemTouchHelperAdapter

public interface ItemTouchHelperAdapter {
  //移动item
  public void onItemMove(int fromPosition,int toPosition);
  //删除item
  public void onItemDelete(int position);
}

之后让Adapter实现这个接口

class MyAdapter extends RecyclerView.Adapter implements ItemTouchHelperAdapter{
 
    LayoutInflater mInflater;
    List mList = addData();
 
    public MyAdapter(Context context) {
      mInflater = LayoutInflater.from(context);
    }
 
    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
      View view = mInflater.inflate(R.layout.item_my_recyclerview,parent,false);
      ViewHolder viewHolder = new ViewHolder(view);
      return viewHolder;
    }
 
    @Override
    public void onBindViewHolder(MyAdapter.ViewHolder holder, int position) {
      holder.mName.setText(mList.get(position).getUserName());
      holder.mDescribe.setText(mList.get(position).getDescription());
    }
 
    @Override
    public int getItemCount() {
      return mList.size();
    }
 
    @Override
    public void onItemMove(int fromPosition, int toPosition) {
      //交换位置
      Collections.swap(mList,fromPosition,toPosition);
      notifyItemMoved(fromPosition,toPosition);
    }
 
    @Override
    public void onItemDelete(int position) {
      //移除数据
      mList.remove(position);
      notifyItemRemoved(position);
    }
 
    public class ViewHolder extends RecyclerView.ViewHolder {
      private TextView mName;
      private TextView mDescribe;
      public ViewHolder(View itemView) {
        super(itemView);
        mName = itemView.findViewById(R.id.txt_name);
        mDescribe = itemView.findViewById(R.id.txt_describe);
      }
    }
  }

接下来我们直接在Callback中直接调用接口里的方法就可以了。

2.新建Callback方法,继承ItemTouchHelper.Callback

官方文档已经告诉我们,使用ItemTouchHelper需要一个Callback,这个Callback是ItemTouchHelper.Callback的子类,我们需要新建一个类来继承ItemTouchHelper.Callback,然后重写一些方法来实现我们的需求。代码如下:

public class myItemTouchHelperCallBack extends ItemTouchHelper.Callback{
  private ItemTouchHelperAdapter itemTouchHelperAdapter;
 
  public myItemTouchHelperCallBack(ItemTouchHelperAdapter itemTouchHelperAdapter) {
    this.itemTouchHelperAdapter = itemTouchHelperAdapter;
  }
 
  @Override
  public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
    //允许上下拖动
    int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
    //允许从右向左滑动
    int swipeFlags = ItemTouchHelper.LEFT;
    return makeMovementFlags(dragFlags,swipeFlags);
  }
 
  @Override
  public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
    //onItemMove接口里的方法
    itemTouchHelperAdapter.onItemMove(viewHolder.getAdapterPosition(),target.getAdapterPosition());
    return true;
  }
 
  @Override
  public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
    //onItemDelete接口里的方法
    itemTouchHelperAdapter.onItemDelete(viewHolder.getAdapterPosition());
  }
 
  @Override
  public boolean isLongPressDragEnabled() {
    //该方法返回值为true时,表示支持长按ItemView拖动
    return true;
  }
 
  @Override
  public boolean isItemViewSwipeEnabled() {
    //该方法返回true时,表示如果用户触摸并且左滑了view,那么可以执行滑动删除操作,就是可以调用onSwiped()方法
    return true;
  }
}

ItemTouchHelper.Callback还有其他几个常用方法:

  1. public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState):从静止状态变为拖拽或者滑动的时候会调用该方法,参数actionState表示当前状态。
  2. public void clearView(RecyclerView recyclerView, ViewHolder viewHolder):当用户操作完某个item并且动画也结束后会调用该方法,一般我们在该方法内恢复ItemView的初始状态,防止由于复用而产生的错乱问题。
  3. public void onChildDraw(…):我们可以在这个方法内实现我们自定义的交互规则或者自定义动画。

这样下来我们就只剩下一步了。

3.为RecyclerView添加ItemTouchHelper

代码如下:

  ItemTouchHelper.Callback callback = new myItemTouchHelperCallBack(myAdapter);
  ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
  touchHelper.attachToRecyclerView(mRecyclerView);

这样,我们就实现了我们的需求,我们一起来看看效果:

好了,我们的需求完成了,效果是不是很炫酷,当然大家可以根据自己的需求做出更炫酷的效果,到时候别忘了与大家一起分享。希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文讲述了如何通过代码在Android中更改Recycler视图项的背景颜色。通过在onBindViewHolder方法中设置条件判断,可以实现根据条件改变背景颜色的效果。同时,还介绍了如何修改底部边框颜色以及提供了RecyclerView Fragment layout.xml和项目布局文件的示例代码。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • Monkey《大话移动——Android与iOS应用测试指南》的预购信息发布啦!
    Monkey《大话移动——Android与iOS应用测试指南》的预购信息已经发布,可以在京东和当当网进行预购。感谢几位大牛给出的书评,并呼吁大家的支持。明天京东的链接也将发布。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文讨论了在Spring 3.1中,数据源未能自动连接到@Configuration类的错误原因,并提供了解决方法。作者发现了错误的原因,并在代码中手动定义了PersistenceAnnotationBeanPostProcessor。作者删除了该定义后,问题得到解决。此外,作者还指出了默认的PersistenceAnnotationBeanPostProcessor的注册方式,并提供了自定义该bean定义的方法。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
author-avatar
手机用户2502910113_707
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有