首先看一下效果圖:

接下來看具體操作:
準備一個删除按鈕的布局,建立button.xml檔案,代碼如下所示:
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="delete"/>
這個布局很簡單,隻有一個按鈕而已。
接着建立MyLIstView繼承自ListView,這就是我們自定義的View了,代碼如下所示:
package com.example.animal;
import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.RelativeLayout;
public class MyListView extends ListView implements OnGestureListener,
OnTouchListener {
boolean isDeleteShow = false;
int itemPosition;
View deleteButton;
ViewGroup itemLayout;
GestureDetector detector;
onDeleteListener deleteListener;
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
detector=new GestureDetector(getContext(), this);
setOnTouchListener(this);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if(isDeleteShow){
// 如果删除按鈕顯示出來
itemLayout.removeView(deleteButton);
deleteButton = null;
isDeleteShow = false;
return false;
}else{
// 如果删除按鈕沒有顯示出來
return detector.onTouchEvent(event);
}
}
@Override
public boolean onDown(MotionEvent e) {
if (isDeleteShow) {
// 如果删除按鈕顯示出來
} else {
// 如果删除按鈕沒有顯示出來
itemPosition = pointToPosition((int) e.getX(), (int) e.getY());
}
return false;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
//當删除按鈕沒有顯示,并且橫向滑動速度大于縱向滑動速度
if (!isDeleteShow && Math.abs(velocityX) > Math.abs(velocityY)) {
deleteButton = LayoutInflater.from(getContext()).inflate(
R.layout.button, null);
deleteButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
itemLayout.removeView(deleteButton);
deleteButton=null;
isDeleteShow=false;
deleteListener.onDelete(itemPosition);
}
});
//動态添加删除按鈕到item視圖上
itemLayout = (ViewGroup) getChildAt(itemPosition
- getFirstVisiblePosition());
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
params.addRule(RelativeLayout.CENTER_VERTICAL);
itemLayout.addView(deleteButton, params);
isDeleteShow=true;
}
return false;
}
public void setDeleteListener(onDeleteListener listener){
deleteListener=listener;
}
public interface onDeleteListener{
void onDelete(int index);
}
}
這裡在MyListView構造方法中建立了一個GestureDetector執行個體用于監聽手勢,然後給MyLIstView注冊了touch監聽事件。然後在onTouch方法中判斷,如果删除按鈕已經顯示,則将它移除,如果沒有顯示,就使用GestureDetector來處理目前手勢。
當手指按下時,會調用OnGestureListener的onDown()方法,在這裡通過pointToPosition()方法來判斷出目前選中的是ListView的哪一行。當手指快速滑動時,會調用onFling()方法,在這裡會去加載delete_button.xml這個布局,然後将删除按鈕添加到目前選中的那一行item上。注意,我們還給删除按鈕添加了一個點選事件,當點選了删除按鈕時就會回調onDeleteListener的onDelete()方法,在回調方法中應該去處理具體的删除操作。
注意:删除listView中的一個項目,其實就是删除listView适配後的一個資料。
在activity_main中,引用自己建立的MyLIstView,如下所示:
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent">
在MainActivity裡,就可以引用了。
package com.example.animal;
import java.util.ArrayList;
import java.util.List;
import com.example.animal.MyListView.onDeleteListener;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class MainActivity extends Activity {
MyListView listView;
MyAdapter myAdapter;
ArrayList arrayList = new ArrayList();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initArrayList();
listView = (MyListView) findViewById(R.id.list);
myAdapter = new MyAdapter(getApplicationContext(), arrayList);
listView.setAdapter(myAdapter);
listView.setDeleteListener(new onDeleteListener() {
@Override
public void onDelete(int index) {
arrayList.remove(index);
myAdapter.notifyDataSetChanged();
}
});
}
private void initArrayList() {
arrayList.add("Content Item 1");
arrayList.add("Content Item 2");
arrayList.add("Content Item 3");
arrayList.add("Content Item 4");
arrayList.add("Content Item 5");
arrayList.add("Content Item 6");
arrayList.add("Content Item 7");
arrayList.add("Content Item 8");
arrayList.add("Content Item 9");
arrayList.add("Content Item 10");
arrayList.add("Content Item 11");
arrayList.add("Content Item 12");
arrayList.add("Content Item 13");
arrayList.add("Content Item 14");
arrayList.add("Content Item 15");
arrayList.add("Content Item 16");
arrayList.add("Content Item 17");
arrayList.add("Content Item 18");
arrayList.add("Content Item 19");
arrayList.add("Content Item 20");
}
}
class MyAdapter extends BaseAdapter {
Context context;
ArrayList list;
public MyAdapter(Context context, ArrayList list) {
this.context = context;
this.list = list;
}
@Override
public int getCount() {
return 10;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
if (convertView == null) {
view = LayoutInflater.from(context).inflate(R.layout.textv, null);
} else {
view = convertView;
}
TextView tv = (TextView) view.findViewById(R.id.text);
tv.setText(list.get(position));
return view;
}
}
MainActivity裡的内容很簡單,我就不再解釋了。
關于,listView裡的小視圖,如下所示:
android:layout_width="match_parent"
android:layout_height="match_parent"
>
android:layout_width="wrap_content"
android:layout_height="100dp"
/>
示範結束。
參考文章:http://blog.csdn.net/guolin_blog/article/details/17357967