仿QQ滑动删除

思路就是利用一个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();  
			}
		});;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值