思路就是利用一个PopupWindow来显示删除的按钮,通过PopupWindow对象来控制什么时候显示,什么时候删除。注意重写dispatchTouchEvent和TouchEvent两个方法。
先看删除Button的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/btn_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:text="删除"
android:background="@drawable/mm_title_back_pressed"/>
</LinearLayout>
在看主页面:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.drision.ui.MyListView
android:id="@+id/listView1"
android:layout_height="wrap_content"
android:layout_width="fill_parent">
</com.drision.ui.MyListView>
</RelativeLayout>
主要看自定义的ListView
package com.drision.ui;
import com.drision.listviewslip.R;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
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 MyListView extends ListView {
private static final String TAG="MyListView";
/**
* 用户滑动的最小距离
*/
private int touchSlop;
private boolean isSliding;
private int xDown;
private int yDown;
private int xMove;
private int yMove;
private LayoutInflater inflater;
private PopupWindow popupWindow;
private int popupHeight;
private int popupWidth;
private Button btn_delete;
//当前手指触摸的view
private View currentView;
private int currentPosition;
private DelButtonClickListener mListener;
//构造函数必须使用这个带attrs,不然报错,我也不晓得为什么,因为我很菜
public MyListView(Context context , AttributeSet attrs) {
super(context, attrs);
inflater = LayoutInflater.from(context);
touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
View view = inflater.inflate(R.layout.delete_btn, null);
btn_delete = (Button) view.findViewById(R.id.btn_delete);
popupWindow = new PopupWindow(view, LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
/**
* 调用measure,否则拿不到宽和高
*/
popupWindow.getContentView().measure(0, 0);
popupHeight = popupWindow.getContentView().getMeasuredHeight();
popupWidth = popupWindow.getContentView().getMeasuredWidth();
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
int action = ev.getAction();
//从右到左滑动
if(isSliding){
switch(action){
case MotionEvent.ACTION_MOVE:
int [] location = new int [2];
//获取当前item的位置
currentView.getLocationOnScreen(location);
//设置popup的动画
popupWindow.setAnimationStyle(R.style.popwindow_delete_btn_anim_style);
popupWindow.update();
popupWindow.showAtLocation(currentView, Gravity.LEFT | Gravity.TOP,
location[0] + currentView.getWidth(), location[1] + currentView.getHeight() / 2
- popupHeight / 2);
btn_delete.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
if(mListener != null){
mListener.clickHappend(currentPosition);
popupWindow.dismiss();
}
}
});
break;
case MotionEvent.ACTION_UP:
isSliding = false;
break;
}
return true;
}
return super.onTouchEvent(ev);
}
@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;
//如果popup显示
if (popupWindow.isShowing())
{
dismissPopWindow();
return false;
}
//获取当前手指按下的item的位置
currentPosition = pointToPosition(xDown, yDown);
//获取当前的item
View view = getChildAt(currentPosition - getFirstVisiblePosition());
currentView = 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){
isSliding = true;
}
break;
}
return super.dispatchTouchEvent(ev);
}
private void dismissPopWindow()
{
if (popupWindow != null && popupWindow.isShowing())
{
popupWindow.dismiss();
}
}
public void setDelButtonClickListener(DelButtonClickListener listener){
mListener = listener;
}
public interface DelButtonClickListener {
public void clickHappend(int position);
}
}
看两个动画的定义:
delete_btn_hide.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromXScale="1.0"
android:toXScale="0.0"
android:fromYScale="1.0"
android:toYScale="1.0"
android:pivotX="100%"
android:pivotY="50%"
android:fillAfter="false"
android:duration="200" >
</scale>
</set>
delete_btn_show.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromXScale="0.0"
android:toXScale="1.0"
android:fromYScale="1.0"
android:toYScale="1.0"
android:pivotX="100%"
android:pivotY="50%"
android:fillAfter="false"
android:duration="200" >
</scale>
</set>
在看主Activity:
package com.drision.listviewslip;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.drision.ui.MyListView.DelButtonClickListener;
import com.drision.ui.MyListView;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Toast;
public class MainActivity extends Activity {
private MyListView listView;
private ArrayAdapter adapter;
private List<String> datas;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (MyListView) this.findViewById(R.id.listView1);
datas = new ArrayList<String>(Arrays.asList("HelloWorld", "Welcome", "Java", "Android", "Servlet", "Struts",
"Hibernate", "Spring", "HTML5", "Javascript", "Lucene"));
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, datas);
listView.setAdapter(adapter);
listView.setDelButtonClickListener(new DelButtonClickListener() {
public void clickHappend(int position) {
Toast.makeText(MainActivity.this, position + " : " + adapter.getItem(position), 1).show();
return;
}
});
listView.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(MainActivity.this, position + " : " + adapter.getItem(position), 1).show();
}
});;
}
}