RecyclerView交互动画 模拟QQ 拖拽、滑动、删除

34 篇文章 1 订阅
4 篇文章 0 订阅

              RecyclerView交互动画 模拟QQ 拖拽、滑动、删除

最近在一个公开课里面看到了这个效果 觉得相当的漂亮,于是记录下来方便 便于之后使用,先看一下效果图

直接上代码了

StartDragListener 

public interface StartDragListener {
    /**
     * 该接口用于需要主动回调拖拽效果的
     * @param viewHolder
     */
     void onStartDrag(RecyclerView.ViewHolder viewHolder);
}
ItemTouchMoveListener
public interface ItemTouchMoveListener {
    /**
     * 当拖拽的时候回调</br>
     * 可以在此方法里面实现:拖拽条目并实现刷新效果
     * @param fromPosition 从什么位置拖
     * @param toPosition	到什么位置
     * @return 是否执行了move
     */
    boolean onItemMove(int fromPosition, int toPosition);

    /**
     * 当条目被移除是回调
     * @param position 移除的位置
     * @return
     */
    boolean onItemRemove(int position);
}
DataUtils 模拟列表数据

public class DataUtils {

    public static List<QQMessage> init(){
        List<QQMessage> list = new ArrayList<QQMessage>();
        list.add(new QQMessage(R.drawable.logo_1, "Java高级交流群", "晓敏老师:不对啊","14:28",R.drawable.pop));

        list.add(new QQMessage(R.drawable.logo_2, "动脑学院一家人", "发个oracel virtual box来","14:23"));

        list.add(new QQMessage(R.drawable.logo_3, "Android开发交流群", "简单:好想躺在床上上班啊","14:28",R.drawable.pop));

        list.add(new QQMessage(R.drawable.logo_4, "群通知", "最新公开课视频已经上传完毕,需要的加晓敏老师QQ","15:12"));

        list.add(new QQMessage(R.drawable.logo_5, "高级装逼扯淡群", "狼伯:叫我兰博","14:28"));

        list.add(new QQMessage(R.drawable.logo_6, "欢乐青年二逼多", "励志要成为车手的年轻人:你不能这样骗我,虽然我年轻","14:28"));

        list.add(new QQMessage(R.drawable.logo_2, "彼尔维何。", "按理说30秒轮询的","17:28"));

        list.add(new QQMessage(R.drawable.logo_1, "腾讯云点播产品交流", "腾讯云点播产品交流 :大神们有 设过 点播和直播的水印的吗","13:28"));

        //--------

        list.add(new QQMessage(R.drawable.logo_1, "Java高级交流群", "晓敏老师:不对啊","14:28",R.drawable.pop));

        list.add(new QQMessage(R.drawable.logo_2, "动脑学院一家人", "发个oracel virtual box来","14:23"));

        list.add(new QQMessage(R.drawable.logo_3, "Android开发交流群", "简单:好想躺在床上上班啊","14:28",R.drawable.pop));

        list.add(new QQMessage(R.drawable.logo_4, "群通知", "最新公开课视频已经上传完毕,需要的加晓敏老师QQ","15:12"));

        list.add(new QQMessage(R.drawable.logo_5, "高级装逼扯淡群", "狼伯:叫我兰博","14:28"));

        list.add(new QQMessage(R.drawable.logo_6, "欢乐青年二逼多", "励志要成为车手的年轻人:你不能这样骗我,虽然我年轻","14:28"));

        list.add(new QQMessage(R.drawable.logo_2, "彼尔维何。", "按理说30秒轮询的","17:28"));

        list.add(new QQMessage(R.drawable.logo_1, "腾讯云点播产品交流", "腾讯云点播产品交流 :大神们有 设过 点播和直播的水印的吗","13:28"));

        list.add(new QQMessage(R.drawable.logo_1, "Java高级交流群", "晓敏老师:不对啊","14:28",R.drawable.pop));

        list.add(new QQMessage(R.drawable.logo_2, "动脑学院一家人", "发个oracel virtual box来","14:23"));

        list.add(new QQMessage(R.drawable.logo_3, "Android开发交流群", "简单:好想躺在床上上班啊","14:28",R.drawable.pop));

        list.add(new QQMessage(R.drawable.logo_4, "群通知", "最新公开课视频已经上传完毕,需要的加晓敏老师QQ","15:12"));

        list.add(new QQMessage(R.drawable.logo_5, "高级装逼扯淡群", "狼伯:叫我兰博","14:28"));

        list.add(new QQMessage(R.drawable.logo_6, "欢乐青年二逼多", "励志要成为车手的年轻人:你不能这样骗我,虽然我年轻","14:28"));

        list.add(new QQMessage(R.drawable.logo_2, "彼尔维何。", "按理说30秒轮询的","17:28"));

        list.add(new QQMessage(R.drawable.logo_1, "腾讯云点播产品交流", "腾讯云点播产品交流 :大神们有 设过 点播和直播的水印的吗","13:28"));

        return list;
    }

}
QQMessage 实体类

public class QQMessage {
    private int logo;
    private String name;
    private String lastMsg;
    private String time;
    private int pop;
    public QQMessage() {
        // TODO Auto-generated constructor stub
    }
    public QQMessage(int logo, String name, String lastMsg, String time) {
        super();
        this.logo = logo;
        this.name = name;
        this.lastMsg = lastMsg;
        this.time = time;
    }
    public QQMessage(int logo, String name, String lastMsg, String time, int pop) {
        super();
        this.logo = logo;
        this.name = name;
        this.lastMsg = lastMsg;
        this.time = time;
        this.pop = pop;
    }
    public int getLogo() {
        return logo;
    }
    public int getPop() {
        return pop;
    }
    public void setPop(int pop) {
        this.pop = pop;
    }
    public void setLogo(int logo) {
        this.logo = logo;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getLastMsg() {
        return lastMsg;
    }
    public void setLastMsg(String lastMsg) {
        this.lastMsg = lastMsg;
    }
    public String getTime() {
        return time;
    }
    public void setTime(String time) {
        this.time = time;
    }
    @Override
    public String toString() {
        return "QQMessage [logo=" + logo + ", name=" + name + ", lastMsg="
                + lastMsg + ", time=" + time + "]";
    }


}
MyAdapter适配器

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> implements ItemTouchMoveListener{
    private List<QQMessage> list;
    private StartDragListener listener;
    public MyAdapter(List<QQMessage> list,StartDragListener listener){
        this.list=list;
        this.listener=listener;
    }
    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view= View.inflate(viewGroup.getContext(),R.layout.list_item,null);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final MyViewHolder viewHolder, int i) {
        QQMessage message=list.get(i);
        viewHolder.iv_logo.setImageResource(message.getLogo());
        viewHolder.tv_name.setText(message.getName());
        viewHolder.tv_Msg.setText(message.getLastMsg());
        viewHolder.tv_time.setText(message.getTime());
        viewHolder.iv_logo.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction()==MotionEvent.ACTION_DOWN){
                    //传递触摸情况给 callback
                    listener.onStartDrag(viewHolder);
                }
                return false;
            }
        });
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    /**
     * 当拖拽的时候回调</br>
     * 可以在此方法里面实现:拖拽条目并实现刷新效果
     *
     * @param fromPosition 从什么位置拖
     * @param toPosition   到什么位置
     * @return 是否执行了move
     */
    @Override
    public boolean onItemMove(int fromPosition, int toPosition) {
        // 1.数据交换;2.刷新
        Collections.swap(list,fromPosition,toPosition);
        notifyItemMoved(fromPosition,toPosition);
        return true;
    }

    /**
     * 当条目被移除是回调
     *
     * @param position 移除的位置
     * @return
     */
    @Override
    public boolean onItemRemove(int position) {
        list.remove(position);
        notifyItemRemoved(position);
        return true;
    }

    class MyViewHolder extends RecyclerView.ViewHolder{
        private ImageView iv_logo;
        private TextView tv_name;
        private TextView tv_Msg;
        private TextView tv_time;
        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            iv_logo = (ImageView)itemView.findViewById(R.id.iv_logo);
            tv_name = (TextView)itemView.findViewById(R.id.tv_name);
            tv_Msg = (TextView)itemView.findViewById(R.id.tv_lastMsg);
            tv_time = (TextView)itemView.findViewById(R.id.tv_time);

        }

    }
}
MyItemTouchHelperCallback 继承了 Callback

public class MyItemTouchHelperCallback extends ItemTouchHelper.Callback {
    private ItemTouchMoveListener listener;
    public MyItemTouchHelperCallback(ItemTouchMoveListener listener){
        this.listener=listener;
    }
    /**
     * 用来判断callback回调监听时,先调用的一个方法 ,比如判断方向(意思就是我要监听哪个方向的拖动)
     * @param recyclerView
     * @param viewHolder
     * @return
     */
    @Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        //方向:up,down,left,right
        //常量:
      /*  int up=ItemTouchHelper.UP;//1  0x0001
        int dowm=ItemTouchHelper.DOWN;//2 0x0010
        int left=ItemTouchHelper.LEFT;
        int right= ItemTouchHelper.RIGHT;*/
        //我要监听的拖拽方向是哪两个方向。
        int dragFlags=ItemTouchHelper.UP |ItemTouchHelper.DOWN;
        //我要监听的swipe侧滑方向是哪个方向
        int swipeFlags=ItemTouchHelper.LEFT |ItemTouchHelper.RIGHT;

        int flags = makeMovementFlags(dragFlags, swipeFlags);
        return flags;
    }

    /**
     * 当移动的时候回调的方法--拖拽
     * @param recyclerView
     * @param srcHolder
     * @param targetHolder
     * @return
     */
    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder srcHolder, @NonNull RecyclerView.ViewHolder targetHolder) {
        // 在拖拽的过程当中不断地调用adapter.notifyItemMoved(from,to);
        if(srcHolder.getItemViewType()!=targetHolder.getItemViewType()){
            return false;
        }
        boolean result=listener.onItemMove(srcHolder.getAdapterPosition(),targetHolder.getAdapterPosition());
        return result;

    }

    /**
     * 侧滑的时候回调的方法
     * @param viewHolder
     * @param i
     */
    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
        // 监听侧滑,1.删除数据;2.调用adapter.notifyItemRemove(position
        listener.onItemRemove(viewHolder.getAdapterPosition());
    }

  /*  @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
        //判断选中状态
        if(actionState!=ItemTouchHelper.ACTION_STATE_IDLE){
            viewHolder.itemView.setBackgroundColor(viewHolder.itemView.getContext().getResources().getColor(R.color.colorAccent));
        }
        super.onSelectedChanged(viewHolder, actionState);
    }
    @Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder ) {
        // 恢复
        viewHolder.itemView.setBackgroundColor(Color.WHITE);
        viewHolder.itemView.setAlpha(1);//1~0
    	viewHolder.itemView.setScaleX(1);//1~0
		viewHolder.itemView.setScaleY(1);//1~0
        super.clearView(recyclerView, viewHolder);
    }
    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView,
                            RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState,
                            boolean isCurrentlyActive) {
        //dX:水平方向移动的增量(负:往左;正:往右)范围:0~View.getWidth  0~1
        if(actionState==ItemTouchHelper.ACTION_STATE_SWIPE){
            //透明度动画
            float alpha = 1-Math.abs(dX)/viewHolder.itemView.getWidth();
            viewHolder.itemView.setAlpha(alpha);//1~0
            viewHolder.itemView.setScaleX(alpha);//1~0
            viewHolder.itemView.setScaleY(alpha);//1~0
        }
        *//*if(Math.abs(dX)<=viewHolder.itemView.getWidth()/2){
            viewHolder.itemView.setTranslationX(-0.5f*viewHolder.itemView.getWidth());
        }else{
            viewHolder.itemView.setTranslationX(dX);
        }*//*
        //此super方法会自动处理 setTranslationX
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState,
                isCurrentlyActive);
    }*/
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="120dp"
        android:background="@drawable/top" />
    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">

    </android.support.v7.widget.RecyclerView>
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="58dp"
        android:background="@drawable/bottom" />

</LinearLayout>

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:gravity="center_vertical"
    android:background="#fff"
    android:paddingLeft="5dip"
    android:paddingRight="5dip"
    android:paddingTop="8dip"
    android:paddingBottom="8dip" >

    <ImageView
        android:id="@+id/iv_logo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/logo_1" />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_marginLeft="10dip" >

        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical" >

            <TextView
                android:id="@+id/tv_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="动脑学院"
                android:layout_alignParentLeft="true"
                android:textColor="#000"
                android:textSize="16sp" />

            <TextView
                android:id="@+id/tv_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="14:31"
                android:layout_alignParentRight="true"
                android:textColor="#a6a6a6"
                android:textSize="12sp"
                android:layout_centerVertical="true"/>
        </RelativeLayout>

        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:gravity="center_vertical"
            android:layout_marginTop="5dip" >

            <TextView
                android:id="@+id/tv_lastMsg"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="晓敏老师:不对啊"
                android:layout_alignParentLeft="true"
                android:textColor="#808080"
                android:textSize="12sp"
                android:layout_centerVertical="true"/>

            <ImageView
                android:id="@+id/iv_pop"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true" />
        </RelativeLayout>
    </LinearLayout>

</LinearLayout>

MainActivity 调用

public class MainActivity extends AppCompatActivity implements StartDragListener{
    private RecyclerView rvView;
    private MyAdapter myAdapter;
    private ItemTouchHelper itemTouchHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initUI();
    }
    private void initUI() {
        rvView = (RecyclerView) findViewById(R.id.rv_view);
        rvView.setLayoutManager(new LinearLayoutManager(this));

        List<QQMessage> list=DataUtils.init();
        myAdapter = new MyAdapter(list,this);

        rvView.setAdapter(myAdapter);
        //RecyclerView 条目触摸辅助类
        ItemTouchHelper.Callback callback = new MyItemTouchHelperCallback(myAdapter);
        itemTouchHelper = new ItemTouchHelper(callback);
        itemTouchHelper.attachToRecyclerView(rvView);


    }
    /**
     * 该接口用于需要主动回调拖拽效果的
     *
     * @param viewHolder
     */
    @Override
    public void onStartDrag(RecyclerView.ViewHolder viewHolder) {
        itemTouchHelper.startDrag(viewHolder);
    }
}

图片资源自行替换,或者找我要

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值