ListView中每一項的內容是由BaseAdapter中的getView()方法來決定的,因此我們需要根據使用者的行為來返回相應的View,所以我們要在適配器中擷取清單項目中的每一個項目,並對該項目添加OnTouch事件的註冊,來決定是否顯示這個按鈕,而在顯示按鈕的情況下,我們需要擷取這個按鈕,並對這個按鈕添加OnClick事件的註冊,因此基本的思路就是:
/* 仿 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;}@Overridepublic int getCount() {return mData.size();}@Overridepublic Object getItem(int Index) {return mData.get(Index);}@Overridepublic long getItemId(int Index) {return Index;}@Overridepublic 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();//HeadermHolder.Header= (ImageView)mConvertView.findViewById(R.id.Image);//ContentmHolder.Content= (TextView)mConvertView.findViewById(R.id.Content);//DeletemHolder.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(){@Overridepublic 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; }}