Android仿QQ左滑删除置顶ListView操作
程序员文章站
2024-02-25 22:35:27
最近闲来无事,于是研究了一下qq的左滑删除效果,尝试着实现了一下,先上效果图:
大致思路原理:
- 通过设置margin实现菜单的显示与隐藏
- 监听onto...
最近闲来无事,于是研究了一下qq的左滑删除效果,尝试着实现了一下,先上效果图:
大致思路原理:
- 通过设置margin实现菜单的显示与隐藏
- 监听ontouchevent,处理滑动事件
上代码
import android.content.context; import android.util.attributeset; import android.util.displaymetrics; import android.view.motionevent; import android.view.viewgroup; import android.view.windowmanager; import android.widget.linearlayout; import android.widget.listview; /** * created by mooreli on 2016/8/8. */ public class slidelistview extends listview { private string tag = getclass().getsimplename(); private int mscreenwidth; private int mdownx; private int mdowny; private int mmenuwidth; private boolean ismenushow; private boolean ismoving; private int moperateposition = -1; private viewgroup mpointchild; private linearlayout.layoutparams mlayoutparams; public slidelistview(context context) { super(context); getscreenwidth(context); } public slidelistview(context context, attributeset attrs) { super(context, attrs); getscreenwidth(context); } public slidelistview(context context, attributeset attrs, int defstyleattr) { super(context, attrs, defstyleattr); getscreenwidth(context); } private void getscreenwidth(context context) { windowmanager manager = (windowmanager) context.getsystemservice(context.window_service); displaymetrics dm = new displaymetrics(); manager.getdefaultdisplay().getmetrics(dm); mscreenwidth = dm.widthpixels; } @override public boolean ontouchevent(motionevent ev) { switch (ev.getaction()) { case motionevent.action_down: performactiondown(ev); break; case motionevent.action_move: performactionmove(ev); break; case motionevent.action_up: performactionup(); break; } return super.ontouchevent(ev); } private void performactiondown(motionevent ev) { mdownx = (int) ev.getx(); mdowny = (int) ev.gety(); //如果点击的不是同一个item,则关掉正在显示的菜单 int position = pointtoposition(mdownx, mdowny); if (ismenushow && position != moperateposition) { turntonormal(); } moperateposition = position; mpointchild = (viewgroup) getchildat(position - getfirstvisibleposition()); if (mpointchild != null) { mmenuwidth = mpointchild.getchildat(1).getlayoutparams().width; mlayoutparams = (linearlayout.layoutparams) mpointchild.getchildat(0).getlayoutparams(); mlayoutparams.width = mscreenwidth; setchildlayoutparams(); } } private boolean performactionmove(motionevent ev) { int nowx = (int) ev.getx(); int nowy = (int) ev.gety(); // if (ismoving) { // if (math.abs(nowy - mdowny) > 0) { // log.e(tag, "kkkkkkk"); // onintercepttouchevent(ev); // } // } if (math.abs(nowx - mdownx) > 0) { //左滑 显示菜单 if (nowx < mdownx) { if (ismenushow) { mlayoutparams.leftmargin = -mmenuwidth; } else { //计算显示的宽度 int scroll = (nowx - mdownx); if (-scroll >= mmenuwidth) { scroll = -mmenuwidth; } mlayoutparams.leftmargin = scroll; } } //右滑 如果菜单显示状态,则关闭菜单 if (ismenushow && nowx > mdownx) { int scroll = nowx - mdownx; if (scroll >= mmenuwidth) { scroll = mmenuwidth; } mlayoutparams.leftmargin = scroll - mmenuwidth; } setchildlayoutparams(); ismoving = true; return true; } return super.ontouchevent(ev); } private void performactionup() { //超过一半时,显示菜单,否则隐藏 if (-mlayoutparams.leftmargin >= mmenuwidth / 2) { mlayoutparams.leftmargin = -mmenuwidth; setchildlayoutparams(); ismenushow = true; } else { turntonormal(); } ismoving = false; } private void setchildlayoutparams(){ if(mpointchild != null){ mpointchild.getchildat(0).setlayoutparams(mlayoutparams); } } /** * 正常显示 */ public void turntonormal() { mlayoutparams.leftmargin = 0; moperateposition = -1; setchildlayoutparams(); ismenushow = false; } }
item的布局要注意,因为在自定义view中写死的是获取第一个子布局为显示内容,所以需要将显示的样式写在一个容器中,将菜单写在另一个容器中,两个平行的关系。
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:background="#ffffff" android:orientation="horizontal"> <linearlayout android:layout_width="match_parent" android:layout_height="60dp" android:orientation="horizontal"> <textview android:id="@+id/main_tv_title" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginleft="10dp" android:gravity="center_vertical" android:textsize="18sp" /> </linearlayout> <linearlayout android:layout_width="180dp" android:layout_height="60dp" android:orientation="horizontal"> <textview android:id="@+id/main_tv_delete" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="#ff0000" android:gravity="center" android:text="删除" android:textcolor="#ffffff" /> <textview android:id="@+id/main_tv_top" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="#dfcdbf" android:gravity="center" android:text="置顶" android:textcolor="#ffffff" /> </linearlayout> </linearlayout>
最后就是删除操作与置顶操作,这个就比较简单,给按钮添加点击事件即可。我是在adapter中定义实现,记得操作后要将菜单关掉!
上部分代码:
holder.tvtitle.settext(minfos.get(position)); holder.tvdelete.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { minfos.remove(position); notifydatasetchanged(); mlistview.turntonormal(); } }); holder.tvtop.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { string temp = minfos.get(position); minfos.remove(position); minfos.add(0, temp); notifydatasetchanged(); mlistview.turntonormal(); } });
最后还有一个遗留问题,listview左右滑动的时候上下也会滑动,这个有待探索与改进,也希望大家提提意见,帮我改进!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。