Android 可拖拽上下交换项目的列表

本文介绍如何在Android项目中实现一个可拖拽并交换数据的列表视图。通过自定义DragListAdapter适配器和DragListView,实现列表项的拖放操作。详细讲述了适配器和列表视图的关键代码,包括数据交换、项目隐藏等功能,并展示了运行效果。
摘要由CSDN通过智能技术生成

前几天由于项目需求,需要做一个可拖拽交叉项目数据的列表视图,网上找了很多都是针对享有项目而做的,具有针对性,不便于代码移植,再对多个可拖拽列表代码的参考后自己写了一个拖拽列表视图控件及针对该视图写的数据适配器,废话不多说,直接上代码**(部分代码来源于网络)**:

1、DragListAdapter适配器代码:

package com.ble.konshine.adapter; //这里包名称可以根据自己的项目修改
import androidx.annotation.Nullable;
import android.database.DataSetObservable;
import android.database.DataSetObserver;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;


public abstract class DragListAdapter  implements ListAdapter {
   
    private final DataSetObservable mDataSetObservable = new DataSetObservable();
    private CharSequence[] mAutofillOptions;

    /**
     * 拖拽时需要交换的两个数据项的位置
     * @param firstPosition 第一交换位置
     * @param secondPosition 第二交换位置
     * @return true 数据交换成功,false 未作数据交换处理
     */
    public abstract boolean swapData(int firstPosition,int secondPosition);
    /**交换开始*/
    public abstract void swapStart();
    /**交换完成*/
    public abstract void swapStop();
    @Override
    public boolean hasStableIds() {
   
        return false;
    }
    @Override
    public void registerDataSetObserver(DataSetObserver observer) {
   
        mDataSetObservable.registerObserver(observer);
    }

    @Override
    public void unregisterDataSetObserver(DataSetObserver observer) {
   
        mDataSetObservable.unregisterObserver(observer);
    }
    /**通知附加的观察者基础数据已更改,任何反映数据集的视图都应自行刷新。*/
    public void notifyDataSetChanged() {
   
        mDataSetObservable.notifyChanged();
    }
    /**
     * 通知附加的观察者基础数据不再有效或不可用。
     * 一旦调用,此适配器将不再有效,不应报告进一步的数据集更改。
     */
    public void notifyDataSetInvalidated() {
   
        mDataSetObservable.notifyInvalidated();
    }
    @Override
    public boolean areAllItemsEnabled() {
   
        return true;
    }
    @Override
    public boolean isEnabled(int position) {
   
        return true;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
   
        return getView(position, convertView, parent);
    }

    public int getItemViewType(int position) {
   
        return 0;
    }

    public int getViewTypeCount() {
   
        return 1;
    }

    public boolean isEmpty() {
   
        return getCount() == 0;
    }

    @Override
    public CharSequence[] getAutofillOptions() {
   
        return mAutofillOptions;
    }
    /**
     * 设置返回的值{@link #getAutofillOptions()}
     */
    public void setAutofillOptions(@Nullable CharSequence... options) {
   
        mAutofillOptions = options;
    }
}

2、DragListView拖拽列表视代码:

package com.ble.konshine.view; //这里包名称可以根据自己的项目修改

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;

import com.ble.konshine.adapter.DragListAdapter;//这里适配器的引用根据自己项目的位置重新引用
//项目视图的隐藏与显示建议不要再这里面处理,会出现找不到项目视图的问题。建议再适配器里面处理
/**
 * 注册项目拖拽的列表视图。如果要使用拖拽请重写{@link DragListAdapter}适配器。
 * 需要继承适配器的{@link DragListAdapter#swapStart()},
 * {@link DragListAdapter#swapData(int, int)},
 * {@link DragListAdapter#swapStop()}这三个方法来处理需要交换的数据及需要隐藏的项,
 * 然后再{@link DragListAdapter#getView(int, View, ViewGroup)}方法中对项目视图进行隐藏或显示处理。
 * 如下代码片段:<P/>
 * public class TestAdapter extends DragListAdapter {<BR/>
 * &nbsp private List<String> List;<BR/>
 * &nbsp private int hidePosition=-1;<BR/>
 *&nbsp &nbsp public boolean swapData(int firstPosition, int secondPosition) {<BR/>
 * &nbsp &nbsp &nbsp &nbsp String s=List.get(firstPosition);<BR/>
 * &nbsp &nbsp  &nbsp &nbsp List.set(firstPosition,List.get(secondPosition));<BR/>
 * &nbsp &nbsp &nbsp &nbsp List.set(secondPosition,s);<BR/>
 * &nbsp &nbsp &nbsp &nbsp hidePosition=secondPosition;<BR/>
 *  &nbsp &nbsp &nbsp &nbsp notifyDataSetChanged();<BR/>
 *  &nbsp &nbsp &nbsp  &nbsp return true;<BR/>
 *    &nbsp &nbsp &nbsp  }<BR/>
 *     &nbsp &nbsp public void swapStart() {<BR/>
 *     &nbsp &nbsp }<BR/>
 *    &nbsp &nbsp  public void swapStop() {<BR/>
 *  &nbsp &nbsp &nbsp  &nbsp       hidePosition=-1;<BR/>
 *   &nbsp &nbsp &nbsp &nbsp       notifyDataSetInvalidated();<BR/>
 *    &nbsp &nbsp &nbsp  }<BR/>
 *    &nbsp &nbsp &nbsp  public View getView(int position, View convertView, ViewGroup parent) {<BR/>
 *        &nbsp &nbsp &nbsp &nbsp  ViewHolder viewHolder;<BR/>
 *        &nbsp &nbsp &nbsp &nbsp  if (convertView == null) {<BR/>
 *          &nbsp &nbsp &nbsp &nbsp &nbsp    convertView= View.inflate(context, R.layout.room_view,null);<BR/>
 *            &nbsp &nbsp &nbsp &nbsp &nbsp  viewHolder=new ViewHolder(convertView);<BR/>
 *            &nbsp &nbsp &nbsp &nbsp &nbsp   convertView.setTag(viewHolder);<BR/>
 *        &nbsp &nbsp &nbsp &nbsp }else{<BR/>
 *            &nbsp &nbsp &nbsp &nbsp &nbsp   viewHolder= (ViewHolder) convertView.getTag();<BR/>
 *         &nbsp &nbsp &nbsp &nbsp   }<BR/>
 *         &nbsp &nbsp &nbsp &nbsp   if(hidePosition==position){<BR/>
 *            &nbsp &nbsp &nbsp &nbsp &nbsp   convertView.setVisibility(View.INVISIBLE);<BR/>
 *         &nbsp &nbsp &nbsp &nbsp  }else{<BR/>
 *            &nbsp &nbsp &nbsp &nbsp &nbsp   convertView.setVisibility(View.VISIBLE);<BR/>
 *          &nbsp &nbsp &nbsp &nbsp   }<BR/>
 *     &nbsp &nbsp &nbsp  }<BR/>
 *   &nbsp &nbsp    }
 */
public class DragListView extends ListView {
   
    /**拖拽视图资源ID*/
    private int draggerViewId;
    private ImageView mDragView;
    private WindowManager mWindowManager;
    private WindowManager.LayoutParams mWindowParams;
    /**正在拖动哪个项目*/
    private int mDragPosition;
    /**拖拽项原始位置*/
    private int mFirstDragmDragPosition;
    /**用户在项目内部的偏移量是多少*/
    private int mDragPoint;
    /** 屏幕坐标和此视图中坐标之间的偏移*/
    private int mCoordOffset;
    /**视图高度*/
    private int mHeight;
    /**在我们认为用户正在滚动之前,触摸可以移动的距离(以像素为单位)*/
    private final int mTouchSlop;
    /**上边界*/
    private int mUpperBound;
    /**下边界*/
    private int mLowerBound;
    private int mItemHeightNormal;
    private Rect mTempRect = new Rect();
    private boolean isLock;// 是否上锁.

    private final static int step = 1;// ListView 滑动步伐.
    private int current_Step;// 当前步伐.

    private<
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值