【转】Android 实现ListView的滑动删除效果
http://www.cnblogs.com/weixiao870428/p/3524055.html
http://download.csdn.net/download/love_javc_you/8533495
首先,这是转载过来的,里面对于手势以及事件分发部分写的还比较可以
用过微信的都知道,微信对话列表滑动删除效果是很不错的,这个效果我们也可以有。思路其实很简单,弄个ListView,然后里面的每个item做成一个可以滑动的自定义控件即可。由于ListView是上下滑动而item是左右滑动,因此会有滑动冲突,也许你需要了解下android中点击事件的派发流程,请参考Android源码分析-点击事件派发机制。我的解决思路是这样的:重写ListView的onInterceptTouchEvent方法,在move的时候做判断,如果是左右滑动就返回false,否则返回true;重写SlideView(即自定义item控件)的onTouchEvent方法来处理滑动。整个思路没有问题,滑动冲突也解决了,可是ListView无法得到焦点了,也就是ListView无法处理点击事件了。让我们回想下问题出在哪里:我的理解是这样的,上述处理滑动本身没有问题,但是有一个副作用,就是会让外层View失去焦点且无法处理点击事件。常见的滑动冲突场景,比如launcher内部嵌入ListView却是没有问题的,因为这个时候launcher不需要获得焦点,需要获得焦点的是内部的ListView。因此,上述处理方式对于外部需要获得焦点的情况(比如外部是ListView)就不太适合了。于是我就和ttdevs探讨,发现他采用了另外一种思路,我从来没有想过还可以这样玩。下面介绍他的思路。
新的思路
不考虑那么复杂,不采用主流玩法,所有的事件均由外层的ListView做拦截,同时把事件传递给SlideView做滑动,这种实现的确可以达到效果,而且代码很简单,根本不需要处理什么复杂的滑动冲突。
效果
下面分别为微信和高仿效果
代码分析
先看SlideView是如何实现的
看layout xml:
- <?xml version="1.0" encoding="utf-8"?>
- <merge xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
- <LinearLayout
- android:id="@+id/view_content"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal" >
- </LinearLayout>
- <RelativeLayout
- android:id="@+id/holder"
- android:layout_width="120dp"
- android:layout_height="match_parent"
- android:clickable="true"
- android:background="@drawable/holder_bg">
- <TextView
- android:id="@+id/delete"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:drawableLeft="@drawable/del_icon_normal"
- android:layout_centerInParent="true"
- android:gravity="center"
- android:textColor="@color/floralwhite"
- android:text="删除" />
- </RelativeLayout>
- </merge>
- <?xml version="1.0" encoding="utf-8"?>
- <merge xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
- <LinearLayout
- android:id="@+id/view_content"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal" >
- </LinearLayout>
- <RelativeLayout
- android:id="@+id/holder"
- android:layout_width="120dp"
- android:layout_height="match_parent"
- android:clickable="true"
- android:background="@drawable/holder_bg">
- <TextView
- android:id="@+id/delete"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:drawableLeft="@drawable/del_icon_normal"
- android:layout_centerInParent="true"
- android:gravity="center"
- android:textColor="@color/floralwhite"
- android:text="删除" />
- </RelativeLayout>
- </merge>
上述xml文件中,所有的view都会被放在view_content中,而holder是放置诸如删除按钮之类的东西,我们的SlideView会加载这个布局。
再看SlideView.java:
- /**
- * SlideView 继承自LinearLayout
- */
- public class SlideView extends LinearLayout {
- private static final String TAG = "SlideView";
- private Context mContext;
- // 用来放置所有view的容器
- private LinearLayout mViewContent;
- // 用来放置内置view的容器,比如删除 按钮
- private RelativeLayout mHolder;
- // 弹性滑动对象,提供弹性滑动效果
- private Scroller mScroller;
- // 滑动回调接口,用来向上层通知滑动事件
- private OnSlideListener mOnSlideListener;
- // 内置容器的宽度 单位:dp
- private int mHolderWidth = 120;
- // 分别记录上次滑动的坐标
- private int mLastX = 0;
- private int mLastY = 0;
- // 用来控制滑动角度,仅当角度a满足如下条件才进行滑动:tan a = deltaX / deltaY > 2
- private static final int TAN = 2;
- public interface OnSlideListener {
- // SlideView的三种状态:开始滑动,打开,关闭
- public static final int SLIDE_STATUS_OFF = 0;
- public static final int SLIDE_STATUS_START_SCROLL = 1;
- public static final int SLIDE_STATUS_ON = 2;
- /**
- * @param view
- * current SlideView
- * @param status
- * SLIDE_STATUS_ON, SLIDE_STATUS_OFF or
- * SLIDE_STATUS_START_SCROLL
- */
- public void onSlide(View view, int status);
- }
- public SlideView(Context context) {
- super(context);
- initView();
- }
- public SlideView(Context context, AttributeSet attrs) {
- super(context, attrs);
- initView();
- }
- private void initView() {
- mContext = getContext();
- // 初始化弹性滑动对象
- mScroller = new Scroller(mContext);
- // 设置其方向为横向
- setOrientation(LinearLayout.HORIZONTAL);
- // 将slide_view_merge加载进来
- View.inflate(mContext, R.layout.slide_view_merge, this);
- mViewContent = (LinearLayout) findViewById(R.id.view_content);
- mHolderWidth = Math.round(TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_DIP, mHolderWidth, getResources()
- .getDisplayMetrics()));
- }
- // 设置按钮的内容,也可以设置图标啥的,我没写
- public void setButtonText(CharSequence text) {
- ((TextView) findViewById(R.id.delete)).setText(text);
- }
- // 将view加入到ViewContent中
- public void setContentView(View view) {
- mViewContent.addView(view);
- }
- // 设置滑动回调
- public void setOnSlideListener(OnSlideListener onSlideListener) {
- mOnSlideListener = onSlideListener;
- }
- // 将当前状态置为关闭
- public void shrink() {
- if (getScrollX() != 0) {
- this.smoothScrollTo(0, 0);
- }
- }
- // 根据MotionEvent来进行滑动,这个方法的作用相当于onTouchEvent
- // 如果你不需要处理滑动冲突,可以直接重命名,照样能正常工作
- public void onRequireTouchEvent(MotionEvent event) {
- int x = (int) event.getX();
- int y = (int) event.getY();
- int scrollX = getScrollX();
- Log.d(TAG, "x=" + x + " y=" + y);
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN: {
- if (!mScroller.isFinished()) {
- mScroller.abortAnimation();
- }
- if (mOnSlideListener != null) {
- mOnSlideListener.onSlide(this,
- OnSlideListener.SLIDE_STATUS_START_SCROLL);
- }
- break;
- }
- case MotionEvent.ACTION_MOVE: {
- int deltaX = x - mLastX;
- int deltaY = y - mLastY;
- if (Math.abs(deltaX) < Math.abs(deltaY) * TAN) {
- // 滑动不满足条件,不做横向滑动
- break;
- }
- // 计算滑动终点是否合法,防止滑动越界
- int newScrollX = scrollX - deltaX;
- if (deltaX != 0) {
- if (newScrollX < 0) {
- newScrollX = 0;
- } else if (newScrollX > mHolderWidth) {
- newScrollX = mHolderWidth;
- }
- this.scrollTo(newScrollX, 0);
- }
- break;
- }
- case MotionEvent.ACTION_UP: {
- int newScrollX = 0;
- // 这里做了下判断,当松开手的时候,会自动向两边滑动,具体向哪边滑,要看当前所处的位置
- if (scrollX - mHolderWidth * 0.75 > 0) {
- newScrollX = mHolderWidth;
- }
- // 慢慢滑向终点
- this.smoothScrollTo(newScrollX, 0);
- // 通知上层滑动事件
- if (mOnSlideListener != null) {
- mOnSlideListener.onSlide(this,
- newScrollX == 0 ? OnSlideListener.SLIDE_STATUS_OFF
- : OnSlideListener.SLIDE_STATUS_ON);
- }
- break;
- }
- default:
- break;
- }
- mLastX = x;
- mLastY = y;
- }
- private void smoothScrollTo(int destX, int destY) {
- // 缓慢滚动到指定位置
- int scrollX = getScrollX();
- int delta = destX - scrollX;
- // 以三倍时长滑向destX,效果就是慢慢滑动
- mScroller.startScroll(scrollX, 0, delta, 0, Math.abs(delta) * 3);
- invalidate();
- }
- @Override
- public void computeScroll() {
- if (mScroller.computeScrollOffset()) {
- scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
- postInvalidate();
- }
- }
- }
- /**
- * SlideView 继承自LinearLayout
- */
- public class SlideView extends LinearLayout {
- private static final String TAG = "SlideView";
- private Context mContext;
- // 用来放置所有view的容器
- private LinearLayout mViewContent;
- // 用来放置内置view的容器,比如删除 按钮
- private RelativeLayout mHolder;
- // 弹性滑动对象,提供弹性滑动效果
- private Scroller mScroller;
- // 滑动回调接口,用来向上层通知滑动事件
- private OnSlideListener mOnSlideListener;
- // 内置容器的宽度 单位:dp
- private int mHolderWidth = 120;
- // 分别记录上次滑动的坐标
- private int mLastX = 0;
- private int mLastY = 0;
- // 用来控制滑动角度,仅当角度a满足如下条件才进行滑动:tan a = deltaX / deltaY > 2
- private static final int TAN = 2;
- public interface OnSlideListener {
- // SlideView的三种状态:开始滑动,打开,关闭
- public static final int SLIDE_STATUS_OFF = 0;
- public static final int SLIDE_STATUS_START_SCROLL = 1;
- public static final int SLIDE_STATUS_ON = 2;
- /**
- * @param view
- * current SlideView
- * @param status
- * SLIDE_STATUS_ON, SLIDE_STATUS_OFF or
- * SLIDE_STATUS_START_SCROLL
- */
- public void onSlide(View view, int status);
- }
- public SlideView(Context context) {
- super(context);
- initView();
- }
- public SlideView(Context context, AttributeSet attrs) {
- super(context, attrs);
- initView();
- }
- private void initView() {
- mContext = getContext();
- // 初始化弹性滑动对象
- mScroller = new Scroller(mContext);
- // 设置其方向为横向
- setOrientation(LinearLayout.HORIZONTAL);
- // 将slide_view_merge加载进来
- View.inflate(mContext, R.layout.slide_view_merge, this);
- mViewContent = (LinearLayout) findViewById(R.id.view_content);
- mHolderWidth = Math.round(TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_DIP, mHolderWidth, getResources()
- .getDisplayMetrics()));
- }
- // 设置按钮的内容,也可以设置图标啥的,我没写
- public void setButtonText(CharSequence text) {
- ((TextView) findViewById(R.id.delete)).setText(text);
- }
- // 将view加入到ViewContent中
- public void setContentView(View view) {
- mViewContent.addView(view);
- }
- // 设置滑动回调
- public void setOnSlideListener(OnSlideListener onSlideListener) {
- mOnSlideListener = onSlideListener;
- }
- // 将当前状态置为关闭
- public void shrink() {
- if (getScrollX() != 0) {
- this.smoothScrollTo(0, 0);
- }
- }
- // 根据MotionEvent来进行滑动,这个方法的作用相当于onTouchEvent
- // 如果你不需要处理滑动冲突,可以直接重命名,照样能正常工作
- public void onRequireTouchEvent(MotionEvent event) {
- int x = (int) event.getX();
- int y = (int) event.getY();
- int scrollX = getScrollX();
- Log.d(TAG, "x=" + x + " y=" + y);
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN: {
- if (!mScroller.isFinished()) {
- mScroller.abortAnimation();
- }
- if (mOnSlideListener != null) {
- mOnSlideListener.onSlide(this,
- OnSlideListener.SLIDE_STATUS_START_SCROLL);
- }
- break;
- }
- case MotionEvent.ACTION_MOVE: {
- int deltaX = x - mLastX;
- int deltaY = y - mLastY;
- if (Math.abs(deltaX) < Math.abs(deltaY) * TAN) {
- // 滑动不满足条件,不做横向滑动
- break;
- }
- // 计算滑动终点是否合法,防止滑动越界
- int newScrollX = scrollX - deltaX;
- if (deltaX != 0) {
- if (newScrollX < 0) {
- newScrollX = 0;
- } else if (newScrollX > mHolderWidth) {
- newScrollX = mHolderWidth;
- }
- this.scrollTo(newScrollX, 0);
- }
- break;
- }
- case MotionEvent.ACTION_UP: {
- int newScrollX = 0;
- // 这里做了下判断,当松开手的时候,会自动向两边滑动,具体向哪边滑,要看当前所处的位置
- if (scrollX - mHolderWidth * 0.75 > 0) {
- newScrollX = mHolderWidth;
- }
- // 慢慢滑向终点
- this.smoothScrollTo(newScrollX, 0);
- // 通知上层滑动事件
- if (mOnSlideListener != null) {
- mOnSlideListener.onSlide(this,
- newScrollX == 0 ? OnSlideListener.SLIDE_STATUS_OFF
- : OnSlideListener.SLIDE_STATUS_ON);
- }
- break;
- }
- default:
- break;
- }
- mLastX = x;
- mLastY = y;
- }
- private void smoothScrollTo(int destX, int destY) {
- // 缓慢滚动到指定位置
- int scrollX = getScrollX();
- int delta = destX - scrollX;
- // 以三倍时长滑向destX,效果就是慢慢滑动
- mScroller.startScroll(scrollX, 0, delta, 0, Math.abs(delta) * 3);
- invalidate();
- }
- @Override
- public void computeScroll() {
- if (mScroller.computeScrollOffset()) {
- scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
- postInvalidate();
- }
- }
- }
上述代码做了很详细的说明,这就是滑动控件的完整代码,大家要明白的是:你所添加的view都是加在SlideView的子View : view_content中的,而不是直接加在SlideView中,只有这样我们才方便做滑动效果。
接着看ListView的代码:核心就是下面这一个方法,将点击事件发送给SlideView处理。
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN: {
- int x = (int) event.getX();
- int y = (int) event.getY();
- //我们想知道当前点击了哪一行
- int position = pointToPosition(x, y);
- Log.e(TAG, "postion=" + position);
- if (position != INVALID_POSITION) {
- //得到当前点击行的数据从而取出当前行的item。
- //可能有人怀疑,为什么要这么干?为什么不用getChildAt(position)?
- //因为ListView会进行缓存,如果你不这么干,有些行的view你是得不到的。
- MessageItem data = (MessageItem) getItemAtPosition(position);
- mFocusedItemView = data.slideView;
- Log.e(TAG, "FocusedItemView=" + mFocusedItemView);
- }
- }
- default:
- break;
- }
- //向当前点击的view发送滑动事件请求,其实就是向SlideView发请求
- if (mFocusedItemView != null) {
- mFocusedItemView.onRequireTouchEvent(event);
- }
- return super.onTouchEvent(event);
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN: {
- int x = (int) event.getX();
- int y = (int) event.getY();
- //我们想知道当前点击了哪一行
- int position = pointToPosition(x, y);
- Log.e(TAG, "postion=" + position);
- if (position != INVALID_POSITION) {
- //得到当前点击行的数据从而取出当前行的item。
- //可能有人怀疑,为什么要这么干?为什么不用getChildAt(position)?
- //因为ListView会进行缓存,如果你不这么干,有些行的view你是得不到的。
- MessageItem data = (MessageItem) getItemAtPosition(position);
- mFocusedItemView = data.slideView;
- Log.e(TAG, "FocusedItemView=" + mFocusedItemView);
- }
- }
- default:
- break;
- }
- //向当前点击的view发送滑动事件请求,其实就是向SlideView发请求
- if (mFocusedItemView != null) {
- mFocusedItemView.onRequireTouchEvent(event);
- }
- return super.onTouchEvent(event);
- }
最后看Activity的代码:
- public class MainActivity extends Activity implements OnItemClickListener,
- OnClickListener, OnSlideListener {
- private static final String TAG = "MainActivity";
- private ListViewCompat mListView;
- private List<MessageItem> mMessageItems = new ArrayList<MainActivity.MessageItem>();
- private SlideAdapter mSlideAdapter;
- // 上次处于打开状态的SlideView
- private SlideView mLastSlideViewWithStatusOn;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- initView();
- }
- private void initView() {
- mListView = (ListViewCompat) findViewById(R.id.list);
- for (int i = 0; i < 20; i++) {
- MessageItem item = new MessageItem();
- if (i % 3 == 0) {
- item.iconRes = R.drawable.default_qq_avatar;
- item.title = "腾讯新闻";
- item.msg = "青岛爆炸满月:大量鱼虾死亡";
- item.time = "晚上18:18";
- } else {
- item.iconRes = R.drawable.wechat_icon;
- item.title = "微信团队";
- item.msg = "欢迎你使用微信";
- item.time = "12月18日";
- }
- mMessageItems.add(item);
- }
- mSlideAdapter = new SlideAdapter();
- mListView.setAdapter(mSlideAdapter);
- mListView.setOnItemClickListener(this);
- }
- private class SlideAdapter extends BaseAdapter {
- private LayoutInflater mInflater;
- SlideAdapter() {
- super();
- mInflater = getLayoutInflater();
- }
- @Override
- public int getCount() {
- return mMessageItems.size();
- }
- @Override
- public Object getItem(int position) {
- return mMessageItems.get(position);
- }
- @Override
- public long getItemId(int position) {
- return position;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- ViewHolder holder;
- SlideView slideView = (SlideView) convertView;
- if (slideView == null) {
- // 这里是我们的item
- View itemView = mInflater.inflate(R.layout.list_item, null);
- slideView = new SlideView(MainActivity.this);
- // 这里把item加入到slideView
- slideView.setContentView(itemView);
- // 下面是做一些数据缓存
- holder = new ViewHolder(slideView);
- slideView.setOnSlideListener(MainActivity.this);
- slideView.setTag(holder);
- } else {
- holder = (ViewHolder) slideView.getTag();
- }
- MessageItem item = mMessageItems.get(position);
- item.slideView = slideView;
- item.slideView.shrink();
- holder.icon.setImageResource(item.iconRes);
- holder.title.setText(item.title);
- holder.msg.setText(item.msg);
- holder.time.setText(item.time);
- holder.deleteHolder.setOnClickListener(MainActivity.this);
- return slideView;
- }
- }
- public class MessageItem {
- public int iconRes;
- public String title;
- public String msg;
- public String time;
- public SlideView slideView;
- }
- private static class ViewHolder {
- public ImageView icon;
- public TextView title;
- public TextView msg;
- public TextView time;
- public ViewGroup deleteHolder;
- ViewHolder(View view) {
- icon = (ImageView) view.findViewById(R.id.icon);
- title = (TextView) view.findViewById(R.id.title);
- msg = (TextView) view.findViewById(R.id.msg);
- time = (TextView) view.findViewById(R.id.time);
- deleteHolder = (ViewGroup) view.findViewById(R.id.holder);
- }
- }
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position,
- long id) {
- // 这里处理ListItem的点击事件
- Log.e(TAG, "onItemClick position=" + position);
- }
- @Override
- public void onSlide(View view, int status) {
- // 如果当前存在已经打开的SlideView,那么将其关闭
- if (mLastSlideViewWithStatusOn != null
- && mLastSlideViewWithStatusOn != view) {
- mLastSlideViewWithStatusOn.shrink();
- }
- // 记录本次处于打开状态的view
- if (status == SLIDE_STATUS_ON) {
- mLastSlideViewWithStatusOn = (SlideView) view;
- }
- }
- @Override
- public void onClick(View v) {
- // 这里处理删除按钮的点击事件,可以删除对话
- if (v.getId() == R.id.holder) {
- int position = mListView.getPositionForView(v);
- if (position != ListView.INVALID_POSITION) {
- mMessageItems.remove(position);
- mSlideAdapter.notifyDataSetChanged();
- }
- Log.e(TAG, "onClick v=" + v);
- }
- }
- }
- public class MainActivity extends Activity implements OnItemClickListener,
- OnClickListener, OnSlideListener {
- private static final String TAG = "MainActivity";
- private ListViewCompat mListView;
- private List<MessageItem> mMessageItems = new ArrayList<MainActivity.MessageItem>();
- private SlideAdapter mSlideAdapter;
- // 上次处于打开状态的SlideView
- private SlideView mLastSlideViewWithStatusOn;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- initView();
- }
- private void initView() {
- mListView = (ListViewCompat) findViewById(R.id.list);
- for (int i = 0; i < 20; i++) {
- MessageItem item = new MessageItem();
- if (i % 3 == 0) {
- item.iconRes = R.drawable.default_qq_avatar;
- item.title = "腾讯新闻";
- item.msg = "青岛爆炸满月:大量鱼虾死亡";
- item.time = "晚上18:18";
- } else {
- item.iconRes = R.drawable.wechat_icon;
- item.title = "微信团队";
- item.msg = "欢迎你使用微信";
- item.time = "12月18日";
- }
- mMessageItems.add(item);
- }
- mSlideAdapter = new SlideAdapter();
- mListView.setAdapter(mSlideAdapter);
- mListView.setOnItemClickListener(this);
- }
- private class SlideAdapter extends BaseAdapter {
- private LayoutInflater mInflater;
- SlideAdapter() {
- super();
- mInflater = getLayoutInflater();
- }
- @Override
- public int getCount() {
- return mMessageItems.size();
- }
- @Override
- public Object getItem(int position) {
- return mMessageItems.get(position);
- }
- @Override
- public long getItemId(int position) {
- return position;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- ViewHolder holder;
- SlideView slideView = (SlideView) convertView;
- if (slideView == null) {
- // 这里是我们的item
- View itemView = mInflater.inflate(R.layout.list_item, null);
- slideView = new SlideView(MainActivity.this);
- // 这里把item加入到slideView
- slideView.setContentView(itemView);
- // 下面是做一些数据缓存
- holder = new ViewHolder(slideView);
- slideView.setOnSlideListener(MainActivity.this);
- slideView.setTag(holder);
- } else {
- holder = (ViewHolder) slideView.getTag();
- }
- MessageItem item = mMessageItems.get(position);
- item.slideView = slideView;
- item.slideView.shrink();
- holder.icon.setImageResource(item.iconRes);
- holder.title.setText(item.title);
- holder.msg.setText(item.msg);
- holder.time.setText(item.time);
- holder.deleteHolder.setOnClickListener(MainActivity.this);
- return slideView;
- }
- }
- public class MessageItem {
- public int iconRes;
- public String title;
- public String msg;
- public String time;
- public SlideView slideView;
- }
- private static class ViewHolder {
- public ImageView icon;
- public TextView title;
- public TextView msg;
- public TextView time;
- public ViewGroup deleteHolder;
- ViewHolder(View view) {
- icon = (ImageView) view.findViewById(R.id.icon);
- title = (TextView) view.findViewById(R.id.title);
- msg = (TextView) view.findViewById(R.id.msg);
- time = (TextView) view.findViewById(R.id.time);
- deleteHolder = (ViewGroup) view.findViewById(R.id.holder);
- }
- }
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position,
- long id) {
- // 这里处理ListItem的点击事件
- Log.e(TAG, "onItemClick position=" + position);
- }
- @Override
- public void onSlide(View view, int status) {
- // 如果当前存在已经打开的SlideView,那么将其关闭
- if (mLastSlideViewWithStatusOn != null
- && mLastSlideViewWithStatusOn != view) {
- mLastSlideViewWithStatusOn.shrink();
- }
- // 记录本次处于打开状态的view
- if (status == SLIDE_STATUS_ON) {
- mLastSlideViewWithStatusOn = (SlideView) view;
- }
- }
- @Override
- public void onClick(View v) {
- // 这里处理删除按钮的点击事件,可以删除对话
- if (v.getId() == R.id.holder) {
- int position = mListView.getPositionForView(v);
- if (position != ListView.INVALID_POSITION) {
- mMessageItems.remove(position);
- mSlideAdapter.notifyDataSetChanged();
- }
- Log.e(TAG, "onClick v=" + v);
- }
- }
- }
代码我都特意写了注释,就不多说了。
【转】Android 实现ListView的滑动删除效果的更多相关文章
- android 继承ListView实现滑动删除功能.
在一些用户体验较好的应用上,可以经常遇见 在ListView中 向左或向右滑动便可删除那一项列表. 具体实现 则是继承ListView实现特定功能即可. (1). 新建 delete_butt ...
- Android 使用NineOldAndroids实现绚丽的ListView左右滑动删除Item效果
本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/18311877) 今天还是给大家带来自定义控件的编写,自定义一个Lis ...
- 【转】Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果
原文网址:http://blog.csdn.net/xiaanming/article/details/17539199 转帖请注明本文出自xiaanming的博客(http://blog.csdn. ...
- [转]Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果
转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17539199),请尊重他人的辛勤劳动成果,谢谢! 我在上一 ...
- Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果
转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17539199),请尊重他人的辛勤劳动成果,谢谢! 我在上一 ...
- android中列表的滑动删除仿ios滑动删除
大家是不是觉得ios列表的滑动删除效果很酷炫?不用羡慕android也可以实现相同的效果 并且可以自定义效果,比如左滑删除,置顶,收藏,分享等等 其实就是自定义listview重写listview方法 ...
- 原生H5页面模拟APP左侧滑动删除效果
话不多说,往左侧滑动,显示删除,我们先来看一下效果图:如下: 这个布局我就不多说,反正就是一行ul,li, class名“item” js代码如下: $(".item").on(& ...
- android中listview的item滑动删除效果(已解决listview点击问题)
领导看到iphone上tableview有个滑动删除的效果,要求在android上也实现,搜了下资料,实现起来比较简单,可弄到后面,居然不能点击了,把一篇文章中的代码修改了一下,捣鼓了一番,搞定,下面 ...
- ListView滑动删除效果实现
通过继承ListView然后结合PopupWindow实现 首先是布局文件: delete_btn.xml:这里只需要一个Button <?xml version="1.0" ...
随机推荐
- HDU 1232 畅通工程 (并查集,常规)
题意:中文题目 思路:按照HDU1213来做.http://www.cnblogs.com/xcw0754/p/4607813.html #include <bits/stdc++.h> ...
- fzu 1675 The Seventy-seven Problem
给你长度为 10^5~10^6长度,由数字组成的串 其中有4位不见了 补全该串 使得在该串能整除 77的同时 尽可能大// 先计算出每个 n*10^m 模 77 的循环节 n=0,1,2..,9// ...
- 【转】linux : waitpid函数
原文网址:http://blog.csdn.net/jifengszf/article/details/3067841 [waitpid系统调用] 功能描述: 等待进程改变其状态.所有下面 ...
- android中sqlite3常用命令
1)打开数据库 在adb shell模式下执行命令sqlite3 + 数据库名称,例如打开email中的EmailProvider.db数据库: 2)sqlite3特殊命令 大多数候,sqlite3读 ...
- hdu 4081 Qin Shi Huang's National Road System(最小生成树+dp)2011 Asia Beijing Regional Contest
同样是看别人题解才明白的 题目大意—— 话说秦始皇统一六国之后,打算修路.他要用n-1条路,将n个城市连接起来,并且使这n-1条路的距离之和最短.最小生成树是不是?不对,还有呢.接着,一个自称徐福的游 ...
- IOS color 颜色值比较
/生成采样对照颜色(黑色) UIColor* sampleColor = [UIColor colorWithRed:(0/255.0f) green:(0/255.0f) blue:(0/255. ...
- 【SQL server】安装和配置
(1)SQL sever 版本问题1: SQL sever 2000 .SQL sever 2005.SQL sever 2008 .SQL sever 2008 R2 安装的时候需要注意是SQL s ...
- 使用calabash测试开源中国Android客户端
Calabash-android是支持android的UI自动化测试框架,前面已经介绍过<中文Win7下成功安装calabash-android步骤>,这篇博文尝试测试一个真实应用:开源中 ...
- (转)我是如何在SQLServer中处理每天四亿三千万记录的
首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文中有不对的地方,请各位数据库大牛给予指正,以便我能够更好的处理此次业务. ...
- 从表中随机返回n条记录
创建测试用表: CREATE OR REPLACE VIEW V AS SELECT 'a' AS c FROM dual UNION ALL SELECT 'b' AS c FROM dual UN ...