抽象类封装,需要在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;
}
}