欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android程序开发之ListView 与PopupWindow实现从左向右滑动删除功能

程序员文章站 2024-03-31 17:58:22
文章实现的功能是:在listview的item上从右向左滑时,出现删除按钮,点击删除按钮把item删除。 看过文章后,感觉没有必要把dispatchtoucheven...

文章实现的功能是:在listview的item上从右向左滑时,出现删除按钮,点击删除按钮把item删除。

看过文章后,感觉没有必要把dispatchtouchevent()和ontouchevent()两个方法都重写,只要重写ontouchevent就好了。于是对代码作了一些调整:

public class mylistview extends listview {
private static final string tag = "mylistview";
private int mtouchslop;
private int mxdown;
private int mydown;
private int mcurrentposition;
private view mcurrentview;
private popupwindow mpopupwindow;
private layoutinflater minflater;
private boolean issliding = false;
// 为删除按钮提供一个回调接口
private delbuttonclicklistener mlistener;
private button mdelbtn;
private int mpopupwindowheight;
private int mpopupwindowwidth;
public mylistview(context context, attributeset attrs) {
super(context, attrs);
minflater = layoutinflater.from(context);
mtouchslop = viewconfiguration.get(context).getscaledtouchslop();
view view = minflater.inflate(r.layout.delete_btn, null);
mdelbtn = (button) view.findviewbyid(r.id.id_item_btn);
mpopupwindow = new popupwindow(view, linearlayout.layoutparams.wrap_content,
linearlayout.layoutparams.wrap_content);
// 如果需要通过点击popupwindow之外的地方使其消失,则需要setfocusable(true).
mpopupwindow.setfocusable(true);
// android 6.0以前的版本需要setbackgrounddrawable(),
// 才能实现通过点击popupwindow之外的地方使其消失的功能。
mpopupwindow.setbackgrounddrawable(new colordrawable(0));
// 先调用下measure,否则拿不到宽和高
mpopupwindow.getcontentview().measure(0, 0);
mpopupwindowheight = mpopupwindow.getcontentview().getmeasuredheight();
mpopupwindowwidth = mpopupwindow.getcontentview().getmeasuredwidth();
}
@override
public boolean ontouchevent(motionevent ev) {
int action = ev.getaction();
int x = (int) ev.getx();
int y = (int) ev.gety();
switch (action){
case motionevent.action_down:
issliding = false;
mxdown = x;
mydown = y;
mcurrentposition = pointtoposition(mxdown, mydown);
view view = getchildat(mcurrentposition - getfirstvisibleposition());
mcurrentview = view;
break;
case motionevent.action_move:
int dx = x - mxdown;
int dy = y - mydown;
log.d(tag, "mtouchslop = " + mtouchslop + ", dx = " + dx + ", dy = " + dy);
if(mxdown > x && math.abs(dx) > mtouchslop && math.abs(dy) < mtouchslop){
log.d(tag, "issliding");
issliding = true;
int[] location = new int[2];
mcurrentview.getlocationonscreen(location);
mpopupwindow.setanimationstyle(r.style.popwindow_delete_btn_anim_style);
mpopupwindow.update();
log.d(tag, "height: " + mcurrentview.getheight() + "," + mpopupwindow.getheight());
mpopupwindow.showatlocation(mcurrentview, gravity.no_gravity,
location[0] + mcurrentview.getwidth(),
location[1] + mcurrentview.getheight() / 2 - mpopupwindowheight / 2);
mdelbtn.setonclicklistener(new onclicklistener() {
@override
public void onclick(view v) {
mlistener.clickhappend(mcurrentposition);
mpopupwindow.dismiss();
}
});
}
case motionevent.action_up:
// issliding 如果这里恢复为false,则后面会执行super.ontouchevent事件,
// 而abslistview的ontouchevent调用了ontouchup方法,在ontouchup方法中有可能执行
// performclick.run() --> performitemclick() --> super.performitemclick
// --> monitemclicklistener.onitemclick,这样最终触发item的点击。
// 因此此处依旧保持issliding为true的状态,而在action_down事件中恢复issliding为false,
// 毕竟每个事件都以action_down开始。
//issliding = false;
}
if(issliding){
return true;
}
return super.ontouchevent(ev);
}
public void setdelbuttonclicklistener(delbuttonclicklistener listener){
mlistener = listener;
}
interface delbuttonclicklistener{
public void clickhappend(int position);
}
}

通过这个例子学习到:

1、listview的item点击事件的触发过程:

自定义listview的ontouchevent() ---调用super.ontouchevent()---> abslistview.ontouchevent() ---motionevent.action_up---> abslistview.ontouchup()

---(有可能)调用performclick.run()---> abslistview.performclick.run() ---调用performitemclick()---> abslistview.performitemclick()

---(有可能)调用super.performitemclick()---> adapterview.performitemclick() ---monitemclicklistener.onitemclick---> onitemclicklistener.onitemclick()

也就是item的点击事件是在motionevent.action_up事件完成的,这样在自定义listview的ontouchevent()中,对motionevent.action_up直接return true消费掉事件,而不要调用super.ontouchevent。这样就避免了删除按钮与item点击事件的冲突。

2、popupwindow--通过点击popupwindow之外的地方使其消失

a、需要调用setfocusable()方法;

b、android 6.0以前的版本需要setbackgrounddrawable()(具体原因见:popupwindow的使用)。

以上所述是小编给大家介绍的android程序开发之listview 与popupwindow实现滑动删除功能