今天想和大家分享的是手机QQ消息列表侧滑删除效果,这种效果在IOS中被封装为一个列表控件,而手机QQ则是将这个功能移植到了Android上,换言之,这并非是手机QQ的独创。尽管如此,用户体验依然得到了很大的提升。那么,今天就让我们一起来学习实现这个效果吧。
一、实现原理
给每个ListView的项目中添加一个按钮,这个按钮在默认情况下是隐藏的,当用户接触屏幕后,在OnTouch事件里捕捉用户的行为,按照一定的规则来决定是显示还是隐藏按钮,而当按钮处于显示状态时,我们单击该按钮即可实现对该按钮所在项目的删除。这里我们以手指按下和抬起的横坐标作为判断用户是否滑动手指的标准,当两点间距离的绝对值>25时,即认为用户的手指滑动了,在此条件下,决定隐藏按钮还是显示按钮。
二、基本思路
ListView中每一项的内容是由BaseAdapter中的getView()方法来决定的,因此我们需要根据用户的行为来返回相应的View,所以我们要在适配器中获取列表项中的每一个项目,并对该项目添加OnTouch事件的注册,来决定是否显示这个按钮,而在显示按钮的情况下,我们需要获取这个按钮,并对这个按钮添加OnClick事件的注册,因此基本的思路就是:
1、获取列表中的每一项,为其添加OnTouchListener(),实现OnTouch方法,在OnTouch方法里捕捉用户行为,并做出响应
2、对于显示按钮的项目,为其添加OnClickListener(),实现OnClick方法,在OnClick方法里相应用户的点击,notifyDataSetChanged()使用更新列表
三、具体实现
/* 仿 QQ消息滑动删除效果 作者:秦元培 时间:2013年12月26日 这个程序对于手势的识别还不是很好,基本上可以满足要求,但是还需要完善这一部分,例如解决同时点击的问题 */ package com.Android.SliderToRemove; import java.util.List; import java.util.Map; import android.content.Context; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; public class ListViewAdapter extends BaseAdapter { public List<Map<String, Object>> mData; private Context mContext; private float mDownX,mUpX; private Button BtnDelete; private boolean IsShowButton; public ListViewAdapter(Context context,List<Map<String,Object>> data) { this.mData = data; this.mContext = context; } @Override public int getCount() { return mData.size(); } @Override public Object getItem(int Index) { return mData.get(Index); } @Override public long getItemId(int Index) { return Index; } @Override public View getView(final int mPosition, View mConvertView, ViewGroup parent) { ViewHolder mHolder = null; if (mConvertView == null) { mConvertView = LayoutInflater.from(mContext).inflate(R.layout.layout_item,null); mHolder = new ViewHolder(); //Header mHolder.Header= (ImageView)mConvertView.findViewById(R.id.Image); //Content mHolder.Content= (TextView)mConvertView.findViewById(R.id.Content); //Delete mHolder.Delete=(Button)mConvertView.findViewById(R.id.Delete); mConvertView.setTag(mHolder); } else { mHolder = (ViewHolder) mConvertView.getTag(); } //列表项Touch事件绑定 mConvertView.setOnTouchListener(mTouchListener); //列表项中删除按钮的Click事件绑定 mHolder.Delete.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (BtnDelete != null) { BtnDelete.setVisibility(View.GONE); // 点击删除按钮后,影藏按钮 mData.remove(mPosition); // 把数据源里面相应数据删除 notifyDataSetChanged(); // 删除数据,加动画 } } }); //Fuck!这里必须要先进行手势的处理,然后再绑定要显示的内容,否则会出现意外!!!!! mHolder.Header.setBackgroundResource((Integer) mData.get(mPosition).get("Header")); mHolder.Content.setText((CharSequence) mData.get(mPosition).get("Content")); return mConvertView; } OnTouchListener mTouchListener=new OnTouchListener() { @Override public boolean onTouch(View mView, MotionEvent mEvent) { final ViewHolder holder = (ViewHolder)mView.getTag(); BtnDelete=holder.Delete; switch (mEvent.getAction()) { case MotionEvent.ACTION_DOWN: mDownX = mEvent.getX(); if(BtnDelete!=null) { //如果手指按下和抬起的水平距离的绝对值>25,则认为发生了滑动 if (Math.abs(mDownX - mUpX) > 25) { //如果当前按钮是显示,则隐藏,反之,则显示 if(IsShowButton) { //隐藏按钮的渐变动画 HideAnimation(holder.Delete); holder.Delete.setVisibility(View.GONE); IsShowButton=false; } else { //显示按钮的渐变动画 ShowAnimation(holder.Delete); holder.Delete.setVisibility(View.VISIBLE); IsShowButton=true; } //获取当前项目中的删除按钮,便于执行下一步 BtnDelete = holder.Delete; } } break; case MotionEvent.ACTION_UP: mUpX = mEvent.getX(); break; } return true; } }; //显示按钮的渐变动画 public void ShowAnimation(View v) { Animation Ani_Alpha = new AlphaAnimation(0.1f, 1.0f); Ani_Alpha.setDuration(1000); v.setAnimation(Ani_Alpha); } //隐藏按钮的渐变动画 public void HideAnimation(View v) { Animation Ani_Alpha = new AlphaAnimation(1.0f, 0.1f); Ani_Alpha.setDuration(1000); v.setAnimation(Ani_Alpha); } static class ViewHolder { ImageView Header; TextView Content; Button Delete; } }