listview长按后拖动item交换位置的帮助类

抽象类封装,需要在activity中创建帮助类对象并重写交换位置的方法changeItemPosition(数据源中id1,数据源中的id2),和重新显示listview的方法resetListview

关键步骤:

1.listview正常显示后,新建lmxListviewHelper对象并传入listview对象,重写两个抽象方法

2.打开item交换功能--> helper.enableChangeItems(true);

效果,长按某一item后,该条目会变成半透明,此时拖动该item移动到其它条目上,对应条目会开始闪烁,此时抬起手指,被拖动的item和闪烁的item位置互换

闪烁动画一开始没写出,是网上源码,具体出处忘记了

另外暂时没有跨屏拖拽功能(间隔距离超出屏幕长度的两个item将无法交换),后期有空会加上

希望帮到大家,错误之处还望指正

帮助类代码:

package com.example.androidtest;

import android.app.Activity;

import android.util.Log;

import android.view.MotionEvent;

import android.view.View;

import android.view.View.OnTouchListener;

import android.view.animation.AlphaAnimation;

import android.view.animation.Animation;

import android.view.animation.LinearInterpolator;

import android.view.animation.TranslateAnimation;

import android.widget.AdapterView;

import android.widget.AdapterView.OnItemLongClickListener;

import android.widget.ListView;

public abstract class lmxListviewHelper {

ListView lv;

// position1:被拖动的item的id

public int position1 = -1;

// 被拖动的item的view

// public View view1;

// public View view2;

// 被移动的item的原始y坐标

public float y1 = -1;

// 抽象方法 交换listview中两个item的位置

public abstract void changeItemPosition(int p1, int p2);

// 抽象方法 充值listview

public abstract void resetListview();

public lmxListviewHelper(ListView lv) {

super();

this.lv = lv;

}

/**

*

* @Title: enableChangeItems

* @Description: TODO(是否启用长按交换item位置)

* @param @param b true-->启用,false-->禁用

* @return void 返回类型

* @throws

*/

public void enableChangeItems(boolean b) {

if (!b) {

return;

}

// 长按后,确定需要交换的item1的id(position1),确定item1的view

lv.setOnItemLongClickListener(new OnItemLongClickListener() {

@Override

public boolean onItemLongClick(AdapterView<?> parent, View view,

int position, long id) {

// TODO Auto-generated method stub

position1 = position;

y1 = lv.getChildAt(position).getY();

lv.getChildAt(position).setAlpha(0.5f);

return false;

}

});

// ontouch监听

/*

* ACTION_MOVE: 1,item1的视图跟随手指上下移动 2,实时监测当前需要替换的item是哪个,对应的item显示动画效果

*/

lv.setOnTouchListener(new OnTouchListener() {

@Override

public boolean onTouch(View v, MotionEvent event) {

// TODO Auto-generated method stub

switch (event.getAction()) {

case MotionEvent.ACTION_MOVE:

if (position1 == -1) {

// position1==-1为true表明没有长按某条item

break;

}

// item1的视图跟随手指上下移动

lv.getChildAt(position1).setY(event.getY());

// 检测当前覆盖的item

checkItem2(lv.getChildAt(position1).getY());

break;

case MotionEvent.ACTION_UP:

replaceItems(event.getY());

break;

default:

break;

}

return false;

}

});

}

protected void checkItem2(float y) {

// TODO Auto-generated method stub

for (int i = 0; i < lv.getChildCount(); i++) {

Log.i("res", "释放替换item" + i);

if (y > lv.getChildAt(i).getTop()

&& y < lv.getChildAt(i).getBottom()) {

// 当前覆盖了item id=i

startFlick(lv.getChildAt(i));

} else {

lv.getChildAt(i).clearAnimation();

}

}

}

public void replaceItems(float y) {

if (y1 == -1) {

// y1未被赋值过 说明onitemlongclick中没有给y1赋值 说明没有item被长按

Log.i("res", "没有item被长按");

return;

}

for (int i = 0; i < lv.getChildCount(); i++) {

// 漏了这句找了一天多,记得清除动画!!!

lv.getChildAt(i).clearAnimation();

if (y > lv.getChildAt(i).getTop()

&& y < lv.getChildAt(i).getBottom()) {

// 抬起手指时所覆盖的item与长按item交换位置

Log.i("res", "action_up替换下标" + i);

changeItemPosition(position1, i);

position1 = -1;

y1 = -1;

return;

}

}

Log.i("res", "action_up时无符合item");

// 若遍历完成未发现所需替代的项 view1移回原位

clearParams();

}

/*

* 没有交换item,清除各种数据

*/

public void clearParams() {

TranslateAnimation translateAnimation = new TranslateAnimation(lv

.getChildAt(position1).getX(), lv.getChildAt(position1).getX(),

lv.getChildAt(position1).getY(), y1);

translateAnimation.setFillAfter(false);

translateAnimation.setDuration(400);

lv.getChildAt(position1).startAnimation(translateAnimation);

resetListview();

// 若position1是listview的常规元素(非header/footer)

if (position1 < lv.getAdapter().getCount()

&& lv.getChildAt(position1) != null) {

lv.getChildAt(position1).clearAnimation();

}

y1 = -1;

position1 = -1;

resetListview();

}

/*

* 闪烁动画

*/

private void startFlick(View view) {

if (null == view) {

return;

}

if (view.getAnimation() == null) {

Animation alphaAnimation = new AlphaAnimation(1, 0);

alphaAnimation.setDuration(200);

alphaAnimation.setInterpolator(new LinearInterpolator());

alphaAnimation.setRepeatCount(Animation.INFINITE);

alphaAnimation.setRepeatMode(Animation.REVERSE);

view.startAnimation(alphaAnimation);

}

}

/**

*

* 取消View闪烁效果

*

*

*

* */

private void stopFlick(View view) {

if (null == view) {

return;

}

view.clearAnimation();

}

}

Activity中的使用方法:

package com.example.androidtest;

import java.util.ArrayList;

import java.util.HashMap;

import android.app.Activity;

import android.os.Bundle;

import android.util.Log;

import android.view.Menu;

import android.view.MenuItem;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.ListView;

import android.widget.SimpleAdapter;

public class MainActivity extends Activity {

ListView lv;

ArrayList<HashMap<String, String>> datalist;

SimpleAdapter adapter;

Button bn;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

/*

* 设置listview显示数据

*/

lv = (ListView) findViewById(R.id.lv);

datalist = new ArrayList<HashMap<String, String>>();

datalist = getSortData();

adapter = new SimpleAdapter(MainActivity.this, datalist,

R.layout.item_sort_management_listview,

new String[] { "sortName" },

new int[] { R.id.tv_sortManagement_lv });

lv.setAdapter(adapter);

lmxListviewHelper helper = new lmxListviewHelper(lv) {

@Override

public void resetListview() {

// TODO Auto-generated method stub

// listview重新显示

adapter = new SimpleAdapter(MainActivity.this, datalist,

R.layout.item_sort_management_listview,

new String[] { "sortName" },

new int[] { R.id.tv_sortManagement_lv });

lv.setAdapter(adapter);

}

@Override

public void changeItemPosition(int p1, int p2) {

// TODO Auto-generated method stub

// 根据自己listview的类型完成listview的数据源中id为p1和p2的两个item的替换

HashMap<String, String> tempMap = datalist.get(p2);

datalist.set(p2, datalist.get(p1));

datalist.set(p1, tempMap);

adapter = new SimpleAdapter(MainActivity.this, datalist,

R.layout.item_sort_management_listview,

new String[] { "sortName" },

new int[] { R.id.tv_sortManagement_lv });

lv.setAdapter(adapter);

}

};

helper.enableChangeItems(true);

}

/*

* 交换item

*/

public void changeItemPosition(int p1, int p2) {

// TODO Auto-generated method stub

Log.i("res", "交换位置的两项为p1-->" + p1 + "\tp2-->" + p2);

HashMap<String, String> tempMap = new HashMap<String, String>();

tempMap = datalist.get(p2);

datalist.set(p2, datalist.get(p1));

datalist.set(p1, tempMap);

adapter = new SimpleAdapter(MainActivity.this, datalist,

R.layout.item_sort_management_listview,

new String[] { "sortName" },

new int[] { R.id.tv_sortManagement_lv });

lv.setAdapter(null);

Log.i("res", "changeItemPosition交换位置执行");

for (int i = 0; i < datalist.size(); i++) {

Log.i("res",

"item" + i + "\tcontent:" + datalist.get(i).get("sortName"));

}

lv.setAdapter(adapter);

}

/*

* 初始化lv

*/

public ArrayList<HashMap<String, String>> getSortData() {

ArrayList<HashMap<String, String>> sortList = new ArrayList<HashMap<String, String>>();

HashMap<String, String> map;

map = new HashMap<String, String>();

map.put("sortName", "家常小炒");

sortList.add(map);

map = new HashMap<String, String>();

map.put("sortName", "经典川菜");

sortList.add(map);

map = new HashMap<String, String>();

map.put("sortName", "瓦罐煨汤");

sortList.add(map);

map = new HashMap<String, String>();

map.put("sortName", "意面焗饭");

sortList.add(map);

map = new HashMap<String, String>();

map.put("sortName", "精美小食");

sortList.add(map);

return sortList;

}

}

时间: 2024-08-14 15:00:08

listview长按后拖动item交换位置的帮助类的相关文章

Android ListView 长按如何获取item的主键并操作对应数据库元组

============问题描述============ 我做的是一个租房管理系统,大概是现在在对房子操作这个界面,我现在是要长按listView中的某一个Item,要求实现修改和删除功能. This is my house_setting.xml document <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.andr

java数组交换位置,定义临时变量后,交换公式顺序问题

public class array01 { public static void main(String[] args){ int[] array = {32,4,56,34,17,39,68,25};//定义一个无序数组 for(int i=0;i<array.length-1;i++){ for(int j=0;j<array.length-i-1;j++){ if(array[j]>array[j+1]){ int temp = array[j];//定义一个临时变量用于交换位置

Android长按及拖动事件探究

Android中长按拖动还是比较常见的.比如Launcher中的图标拖动及屏幕切换,ListView中item顺序的改变,新闻类App中新闻类别的顺序改变等.下面就这个事件做一下分析. 就目前而言,Android中实现长按事件响应有几种方式,包括: 设置View.OnLongClickListener监听器 通过GestureDetector.OnGestureListener间接获取长按事件 实现View.OnTouchListener,然后在回调中通过MotionEvent判断是否触发了长按

vue卡片拖拽、自动排列交换位置、拖拽数据存取

这是这次系列文章的第一篇,我自己封装了一个用vue实现的拖动卡片组件,并且发布到npm,详细地记录下来了整体制作过程.总共有三篇文章,介绍组件的制作思路和遇到的问题,以及在发布到npm上并下载使用的过程中,发生了什么问题并如何解决. 第一篇为组件封装后的使用文档及介绍 第二篇为组件的实现思路以及遇到的问题 第三篇为将组件打包并上传至npm,如何实现按需加载和下载后使用的问题 这是vue实现的拖动卡片组件,主要实现了: 拖动卡片与其他卡片的位置更换,并且其他卡片根据拖动的位置自动顺移,位置数据实时

listView长按事件内修改ListView对象内容

============问题描述============ 我在ListView的Item长按事件内打开一个弹出窗口,窗口内有一个EditText对象,在这个编辑框内输入文本点确定后,希望可以直接修改掉ListView对象内某个TextView对象的内容:现在ListView长按事件内直接修改没有问题了,只是弹出一个窗口再修改不知道该如何实现: ============解决方案1============ 引用 楼主 hackerlyf 的回复: 我在ListView的Item长按事件内打开一个弹出

Android游戏开发中如何将两个图标交换位置

Android 游戏界面中有时候因为布局的美观,需要将两个图标交换位置.这两个图标不是简单地更改id号就可以的,下面是交换两个图标的方法. 原代码中相关程序: 未修改前: float pic_x=200;float pic_y=130; 需要修改的第一部分程序,这一部分利用定义pic_x,pic_y的将图标绘制在相应的界面位置中. 第一个图标位置绘图 if(backmusicFlag01)        {                      canvas.drawBitmap(backM

ListView长按菜单的实现

网络上查阅,ListView长按菜单有两种方式可以实现     第一种方式,需要三步 一.先定义ListView的长按菜单 ListView listView = (ListView) findViewById(R.id.main_listview); registerForContextMenu(listView); 二.为菜单添加详细的项目标题图标. public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuIn

android listview长按,单击各种事件捕捉

之前一直想总结一下这样知识,后面各种忙,就不想写.还是自已总结一下比较好.listview需要注意事项有很多吧,也是最常用的控件之一.我们可以自动计算listview的高度,当与滚动条一起使用的时候.listview分隔线也可以去掉,或者更改.还有与各种控件一起使用的监听.接下来看看我所介绍的以及效果图. 本文项目demo地址:点击此处下载 一.看项目主要类 package com.example.customlistviewdemo; import java.util.ArrayList; i

Android ListView 长按列表弹出菜单

Android ListView 长按列表弹出菜单 设置长按菜单 listView.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() { @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { menu.add(0, 0, 0, "删除单号"); menu.add