今天实现类似于qq的滑动删除效果,当然也有开源的项目swipelistview可以直接拿来使用,今天自定义一个滑动删除的案例。
首先编写用于删除滑动效果的文件
在res目录下新建anim文件夹,新建pop_in.xml和pop_out.xml文件
pop_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:fromXDelta="100%"
android:toXDelta="90%"
android:duration="400"
android:fromYDelta="0%"
android:toYDelta="0%"
/>
</set>
pop_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:fromXDelta="90%"
android:toXDelta="100%"
android:duration="400"
android:fromYDelta="0%"
android:toYDelta="0%"
/>
</set>
<span style="font-size: 12px; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">然后编写自定义的listview,QQListView.java</span>
<span style="font-size: 12px; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"></span><pre name="code" class="java">package com.example.listviewdelete;
import android.content.Context;
import android.util.AttributeSet;
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.ListView;
import android.widget.PopupWindow;
public class QQListView extends ListView {
private static final String TAG = "QQlistView";
//用户滑动的最小距离
private int touchSlop;
//是否相应滑动
private boolean isSliding;
//手指按下时的x坐标
private int xDown;
//手指按下时的y坐标
private int yDown;
//手指移动时的x坐标
private int xMove;
//手指移动时的y坐标
private int yMove;
private LayoutInflater minflater;
private PopupWindow mPopupWindow;
private int mPopupWindowHeight;
private int mPopupWindowWidth;
private Button mDelBtn;
//为删除按钮提供一个回调接口
private DelButtonClickListener mListener;
//当前手指触摸的view
private View mCurrentView;
//当前手指触摸的位置
private int mCurrentViewPos;
interface DelButtonClickListener {
public void clickHappend(int position);
}
/**
* 必要的一些初始化
* @param context
* @param attrs
*/
public QQListView(Context context, AttributeSet attrs) {
super(context, attrs);
minflater = LayoutInflater.from(context);
touchSlop = ViewConfiguration.get(context).getScaledEdgeSlop();
View view = minflater.inflate(R.layout.delete_btn,null);
mDelBtn = (Button) view.findViewById(R.id.id_item_btn);
mPopupWindow = new PopupWindow(view,android.view.ViewGroup.LayoutParams.WRAP_CONTENT,android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
/**
* 先调用晓measure,否则拿不到宽和高
*/
mPopupWindow.getContentView().measure(0, 0);
mPopupWindowHeight = mPopupWindow.getContentView().getMeasuredHeight();
mPopupWindowWidth = mPopupWindow.getContentView().getMeasuredWidth();
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
int action = ev.getAction();
int x = (int) ev.getX();
int y = (int) ev.getY();
switch (action) {
case MotionEvent.ACTION_DOWN:
xDown = x;
yDown = y;
/**
* 如果当前popwindow显示,则直接隐藏,然后屏蔽listview的touch事件的下传
*/
if (mPopupWindow.isShowing()) {
dismissPopWindow();
return false;
}
//获得当前手指按下时的item位置
mCurrentViewPos = pointToPosition(xDown, yDown);
//获得当前手指按下时的item
View view = getChildAt(mCurrentViewPos-getFirstVisiblePosition());
mCurrentView = 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;
}
default:
break;
}
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
int action = ev.getAction();
/**
* 如果是从右到左的滑动才响应
*/
if (isSliding) {
switch (action) {
case MotionEvent.ACTION_MOVE:
int []location = new int[2];
//获得当前item的位置x与y
mCurrentView.getLocationInWindow(location);
//设置popupwindow的动画
mPopupWindow.setAnimationStyle(R.style.btnshow);
mPopupWindow.update();
mPopupWindow.showAtLocation(mCurrentView,Gravity.LEFT|Gravity.TOP,location[0]+mCurrentView.getWidth(),location[1]+mCurrentView.getHeight()/2
-mPopupWindowHeight/2);
//设置删除按钮回调
mDelBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if (mListener != null) {
mListener.clickHappend(mCurrentViewPos);
mPopupWindow.dismiss();
}
}
});
break;
case MotionEvent.ACTION_UP:
isSliding = false;
default:
break;
}
return true;
}
return super.onTouchEvent(ev);
}
/**
* 隐藏popupwindow
*/
private void dismissPopWindow() {
if (null != mPopupWindow && mPopupWindow.isShowing()) {
mPopupWindow.dismiss();
}
}
public DelButtonClickListener getmListener() {
return mListener;
}
public void setmListener(DelButtonClickListener mListener) {
this.mListener = mListener;
}
}
最后在MainActivity的布局文件中,引用自定义的listview
<span style="font-size: 12px; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"></span><pre name="code" class="html"><span style="font-size: 12px; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">activity_main.xml</span>
<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"
tools:context=".MainActivity" >
<com.example.listviewdelete.QQListView
android:id="@+id/id_listview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
</com.example.listviewdelete.QQListView>
</RelativeLayout>
最后在MainActivity中实现具体的控制效果
<span style="font-size: 12px; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">MainActivity.java</span>
<span style="font-size: 12px; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"></span><pre name="code" class="java">public class MainActivity extends Activity {
private QQListView mListView;
private ArrayAdapter<String>mAdapter;
private List<String>mDatas;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView = (QQListView) findViewById(R.id.id_listview);
//不要直接arrays.aslist
mDatas = new ArrayList<String>(Arrays.asList("hello world","welcome","java","android","struts","hello world","welcome","java","android"));
mAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,mDatas);
mListView.setAdapter(mAdapter);
mListView.setmListener(new DelButtonClickListener() {
@Override
public void clickHappend(int position) {
// TODO Auto-generated method stub
mAdapter.remove(mAdapter.getItem(position));
}
});
mListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this,arg2+":"+mAdapter.getItem(arg2),1000).show();
}
});
}
}
<span style="font-size: 12px; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">
</span>
<span style="font-size: 12px; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">
</span>