博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ListView滑动删除 ,仿腾讯QQ
阅读量:5214 次
发布时间:2019-06-14

本文共 6710 字,大约阅读时间需要 22 分钟。

转载请表明出处:http://blog.csdn.net/lmj623565791/article/details/22961279

在CSDN上开了很多大神们的文章,感觉受益良多,也非常欣赏大家的分享态度,所以决定开始写微博,给大家分享自己的心得。

本来准备在ListView的每个Item的布局上设置一个隐藏的Button,当滑动的时候显示。但是因为每次只要存在一个Button,发现每个Item上的Button相互间不好控制。所以决定继承ListView然后结合PopupWindow。

首先是布局文件:

delete_btn.xml:这里只需要一个Button

主布局文件:activity_main.xml ,ListView的每个Item的样式直接使用了系统的android.R.layout.simple_list_item_1

接下来看看QQListView的实现:

package com.example.listviewitemslidedeletebtnshow;import android.content.Context;import android.util.AttributeSet;import android.view.Gravity;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewConfiguration;import android.widget.Button;import android.widget.LinearLayout;import android.widget.ListView;import android.widget.PopupWindow;public class QQListView extends ListView{	private static final String TAG = "QQlistView";	// private static final int VELOCITY_SANP = 200;	// private VelocityTracker mVelocityTracker;	/**	 * 用户滑动的最小距离	 */	private int touchSlop;	/**	 * 是否响应滑动	 */	private boolean isSliding;	/**	 * 手指按下时的x坐标	 */	private int xDown;	/**	 * 手指按下时的y坐标	 */	private int yDown;	/**	 * 手指移动时的x坐标	 */	private int xMove;	/**	 * 手指移动时的y坐标	 */	private int yMove;	private LayoutInflater mInflater;	private PopupWindow mPopupWindow;	private int mPopupWindowHeight;	private int mPopupWindowWidth;	private Button mDelBtn;	/**	 * 为删除按钮提供一个回调接口	 */	private DelButtonClickListener mListener;	/**	 * 当前手指触摸的View	 */	private View mCurrentView;	/**	 * 当前手指触摸的位置	 */	private int mCurrentViewPos;	/**	 * 必要的一些初始化	 * 	 * @param context	 * @param attrs	 */	public QQListView(Context context, AttributeSet attrs)	{		super(context, attrs);		mInflater = LayoutInflater.from(context);		touchSlop = 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);		/**		 * 先调用下measure,否则拿不到宽和高		 */		mPopupWindow.getContentView().measure(0, 0);		mPopupWindowHeight = mPopupWindow.getContentView().getMeasuredHeight();		mPopupWindowWidth = mPopupWindow.getContentView().getMeasuredWidth();	}	@Override	public boolean dispatchTouchEvent(MotionEvent ev)	{		int action = ev.getAction();		int x = (int) ev.getX();		int y = (int) ev.getY();		switch (action)		{		case MotionEvent.ACTION_DOWN:			xDown = x;			yDown = y;			/**			 * 如果当前popupWindow显示,则直接隐藏,然后屏蔽ListView的touch事件的下传			 */			if (mPopupWindow.isShowing())			{				dismissPopWindow();				return false;			}			// 获得当前手指按下时的item的位置			mCurrentViewPos = pointToPosition(xDown, yDown);			// 获得当前手指按下时的item			View view = getChildAt(mCurrentViewPos - getFirstVisiblePosition());			mCurrentView = view;			break;		case MotionEvent.ACTION_MOVE:			xMove = x;			yMove = y;			int dx = xMove - xDown;			int dy = yMove - yDown;			/**			 * 判断是否是从右到左的滑动			 */			if (xMove < xDown && Math.abs(dx) > touchSlop && Math.abs(dy) < touchSlop)			{				// Log.e(TAG, "touchslop = " + touchSlop + " , dx = " + dx +				// " , dy = " + dy);				isSliding = true;			}			break;		}		return super.dispatchTouchEvent(ev);	}	@Override	public boolean onTouchEvent(MotionEvent ev)	{		int action = ev.getAction();		/**		 * 如果是从右到左的滑动才相应		 */		if (isSliding)		{			switch (action)			{			case MotionEvent.ACTION_MOVE:				int[] location = new int[2];				// 获得当前item的位置x与y				mCurrentView.getLocationOnScreen(location);				// 设置popupWindow的动画				mPopupWindow.setAnimationStyle(R.style.popwindow_delete_btn_anim_style);				mPopupWindow.update();				mPopupWindow.showAtLocation(mCurrentView, Gravity.LEFT | Gravity.TOP,						location[0] + mCurrentView.getWidth(), location[1] + mCurrentView.getHeight() / 2								- mPopupWindowHeight / 2);				// 设置删除按钮的回调				mDelBtn.setOnClickListener(new OnClickListener()				{					@Override					public void onClick(View v)					{						if (mListener != null)						{							mListener.clickHappend(mCurrentViewPos);							mPopupWindow.dismiss();						}					}				});				// Log.e(TAG, "mPopupWindow.getHeight()=" + mPopupWindowHeight);				break;			case MotionEvent.ACTION_UP:				isSliding = false;			}			// 相应滑动期间屏幕itemClick事件,避免发生冲突			return true;		}		return super.onTouchEvent(ev);	}	/**	 * 隐藏popupWindow	 */	private void dismissPopWindow()	{		if (mPopupWindow != null && mPopupWindow.isShowing())		{			mPopupWindow.dismiss();		}	}	public void setDelButtonClickListener(DelButtonClickListener listener)	{		mListener = listener;	}	interface DelButtonClickListener	{		public void clickHappend(int position);	}}
代码注释写得很详细,简单说一下,在dispatchTouchEvent中设置当前是否响应用户滑动,然后在onTouchEvent中判断是否响应,如果响应则popupWindow以动画的形式展示出来。当然屏幕上如果存在PopupWindow则屏幕ListView的滚动与Item的点击,以及从右到左滑动时屏幕Item的click事件。

接下来是MainActivity.java,这里代码很简单不做介绍了。

package com.example.listviewitemslidedeletebtnshow;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.ArrayAdapter;import android.widget.Toast;import com.example.listviewitemslidedeletebtnshow.QQListView.DelButtonClickListener;public class MainActivity extends Activity{	private QQListView mListView;	private ArrayAdapter
mAdapter; private List
mDatas; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mListView = (QQListView) findViewById(R.id.id_listview); // 不要直接Arrays.asList mDatas = new ArrayList
(Arrays.asList("HelloWorld", "Welcome", "Java", "Android", "Servlet", "Struts", "Hibernate", "Spring", "HTML5", "Javascript", "Lucene")); mAdapter = new ArrayAdapter
(this, android.R.layout.simple_list_item_1, mDatas); mListView.setAdapter(mAdapter); mListView.setDelButtonClickListener(new DelButtonClickListener() { @Override public void clickHappend(final int position) { Toast.makeText(MainActivity.this, position + " : " + mAdapter.getItem(position), 1).show(); mAdapter.remove(mAdapter.getItem(position)); } }); mListView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView
parent, View view, int position, long id) { Toast.makeText(MainActivity.this, position + " : " + mAdapter.getItem(position), 1).show(); } }); }}
效果图如下:楼主使用asm.jar以及gifcamera截的gif,由于button的动画很短感觉截图效果很卡不流畅,大家有什么好的截图,还望推荐。有兴趣的还是下载源码看看效果i。

转载于:https://www.cnblogs.com/oversea201405/p/3752054.html

你可能感兴趣的文章
专题训练之AC自动机
查看>>
Spring-hibernate整合
查看>>
C#:重载、重写、隐藏的定义
查看>>
在cxf中使用配置避免增加字段导致客户端必须更新、同步实体属性的问题
查看>>
linux netlink套接字学习资料
查看>>
Day14 自己定义泛型类的使用
查看>>
POJ 1258 Agri-Net
查看>>
LeetCode Solutions : Swap Nodes in Pairs
查看>>
Reverse Integer
查看>>
人事管理系统 c语言版
查看>>
KMP模板
查看>>
java未开源的Unsafe类
查看>>
Direct2D教程(一)Direct2D已经来了,谁是GDI的终结者?
查看>>
leetcode-Majority Element
查看>>
20162306 2016-2017-2《程序设计与数据结构》第八周学习总结
查看>>
[转]全面理解Unity加载和内存管理
查看>>
Python全栈(一)编程语言介绍
查看>>
Oleg and Little Ponies
查看>>
C# 装箱与拆箱转换
查看>>
深入C#数据类型
查看>>