文章转载自http://blog.csdn.net/sinat_27681957/article/details/51854525
最近在研究自定义View,想到了之前想研究的侧滑删除.于是..
先上效果图
思路是这样的:
1:首先先说一下item:item用的LinearLayout布局,删除、编辑分别是写死了宽度的TextView,左边是一个match_parent的RelativeLayout,内容自己随意搞
2:上下滑动和左右滑动的处理:当用户手指滑动时,可以进行坐标的判断,如果Y轴移动距离大,则listview上下滑动;否则当X轴移动距离达到或者超过一个TextView的宽度时,动态控制item的marginLeft为负的两倍TextView的宽度,从而实现滑动效果
3:编辑、删除的点击:编辑、删除在adapter中进行监听,然后自己在adapter中再定义一个监听接口,方便用户在使用listview的activity中进行监听
首先,自定义SlideListView
package com.jxy.swipe;
/**
* Created by JinXinYi on 2017/2/9.
*/
import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.ListView;
public class SlideListView extends ListView {
private int mScreenWidth; // 屏幕宽度
private int mDownX; // 按下点的x值
private int mDownY; // 按下点的y值
private int mDeleteBtnWidth;// 删除按钮的宽度
private boolean isDeleteShown; // 删除按钮是否正在显示
private ViewGroup mPointChild; // 当前处理的item
private LinearLayout.LayoutParams mLayoutParams; // 当前处理的item的LayoutParams
public SlideListView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SlideListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// 获取屏幕宽度
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(dm);
mScreenWidth = dm.widthPixels;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
performActionDown(ev);
break;
case MotionEvent.ACTION_MOVE:
return performActionMove(ev);
case MotionEvent.ACTION_UP:
performActionUp();
break;
}
return super.onTouchEvent(ev);
}
// 处理action_down事件
private void performActionDown(MotionEvent ev) {
if(isDeleteShown) {
turnToNormal();
}
mDownX = (int) ev.getX();
mDownY = (int) ev.getY();
// 获取当前点的item
mPointChild = (ViewGroup) getChildAt(pointToPosition(mDownX, mDownY)
- getFirstVisiblePosition());
// 获取删除按钮的宽度
mDeleteBtnWidth = mPointChild.getChildAt(1).getLayoutParams().width;
mLayoutParams = (LinearLayout.LayoutParams) mPointChild.getChildAt(0)
.getLayoutParams();
mLayoutParams.width = mScreenWidth;
mPointChild.getChildAt(0).setLayoutParams(mLayoutParams);
}
// 处理action_move事件
private boolean performActionMove(MotionEvent ev) {
int nowX = (int) ev.getX();
int nowY = (int) ev.getY();
if(Math.abs(nowX - mDownX) > Math.abs(nowY - mDownY)) {
// 如果向左滑动
if(nowX < mDownX) {
// 计算要偏移的距离
int scroll = (nowX - mDownX) / 2;
// 如果大于了删除按钮的宽度, 则最大为删除按钮的宽度
if(-scroll >= mDeleteBtnWidth) {
scroll = -mDeleteBtnWidth;
}
// 重新设置leftMargin
mLayoutParams.leftMargin = scroll*2;
mPointChild.getChildAt(0).setLayoutParams(mLayoutParams);
}
return true;
}
return super.onTouchEvent(ev);
}
// 处理action_up事件
private void performActionUp() {
// 偏移量大于button的一半,则显示button
// 否则恢复默认
if(-mLayoutParams.leftMargin >= mDeleteBtnWidth / 2) {
mLayoutParams.leftMargin = -mDeleteBtnWidth*2;
isDeleteShown = true;
}else {
turnToNormal();
}
mPointChild.getChildAt(0).setLayoutParams(mLayoutParams);
}
/**
* 变为正常状态
*/
public void turnToNormal() {
mLayoutParams.leftMargin = 0;
mPointChild.getChildAt(0).setLayoutParams(mLayoutParams);
isDeleteShown = false;
}
/**
* 当前是否可点击
* @return 是否可点击
*/
public boolean canClick() {
return !isDeleteShown;
}
}
package com.jxy.swipe;
/**
* Created by JinXinYi on 2017/2/9.
*/
import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.ListView;
public class SlideListView extends ListView {
private int mScreenWidth; // 屏幕宽度
private int mDownX; // 按下点的x值
private int mDownY; // 按下点的y值
private int mDeleteBtnWidth;// 删除按钮的宽度
private boolean isDeleteShown; // 删除按钮是否正在显示
private ViewGroup mPointChild; // 当前处理的item
private LinearLayout.LayoutParams mLayoutParams; // 当前处理的item的LayoutParams
public SlideListView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SlideListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// 获取屏幕宽度
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(dm);
mScreenWidth = dm.widthPixels;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
performActionDown(ev);
break;
case MotionEvent.ACTION_MOVE:
return performActionMove(ev);
case MotionEvent.ACTION_UP:
performActionUp();
break;
}
return super.onTouchEvent(ev);
}
// 处理action_down事件
private void performActionDown(MotionEvent ev) {
if(isDeleteShown) {
turnToNormal();
}
mDownX = (int) ev.getX();
mDownY = (int) ev.getY();
// 获取当前点的item
mPointChild = (ViewGroup) getChildAt(pointToPosition(mDownX, mDownY)
- getFirstVisiblePosition());
// 获取删除按钮的宽度
mDeleteBtnWidth = mPointChild.getChildAt(1).getLayoutParams().width;
mLayoutParams = (LinearLayout.LayoutParams) mPointChild.getChildAt(0)
.getLayoutParams();
mLayoutParams.width = mScreenWidth;
mPointChild.getChildAt(0).setLayoutParams(mLayoutParams);
}
// 处理action_move事件
private boolean performActionMove(MotionEvent ev) {
int nowX = (int) ev.getX();
int nowY = (int) ev.getY();
if(Math.abs(nowX - mDownX) > Math.abs(nowY - mDownY)) {
// 如果向左滑动
if(nowX < mDownX) {
// 计算要偏移的距离
int scroll = (nowX - mDownX) / 2;
// 如果大于了删除按钮的宽度, 则最大为删除按钮的宽度
if(-scroll >= mDeleteBtnWidth) {
scroll = -mDeleteBtnWidth;
}
// 重新设置leftMargin
mLayoutParams.leftMargin = scroll*2;
mPointChild.getChildAt(0).setLayoutParams(mLayoutParams);
}
return true;
}
return super.onTouchEvent(ev);
}
// 处理action_up事件
private void performActionUp() {
// 偏移量大于button的一半,则显示button
// 否则恢复默认
if(-mLayoutParams.leftMargin >= mDeleteBtnWidth / 2) {
mLayoutParams.leftMargin = -mDeleteBtnWidth*2;
isDeleteShown = true;
}else {
turnToNormal();
}
mPointChild.getChildAt(0).setLayoutParams(mLayoutParams);
}
/**
* 变为正常状态
*/
public void turnToNormal() {
mLayoutParams.leftMargin = 0;
mPointChild.getChildAt(0).setLayoutParams(mLayoutParams);
isDeleteShown = false;
}
/**
* 当前是否可点击
* @return 是否可点击
*/
public boolean canClick() {
return !isDeleteShown;
}
}
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private SlideListView listView;
private List list=new ArrayList();
private ListViewSlideAdapter listViewSlideAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getData();
initView();
}
private void initView(){
listView=(SlideListView)findViewById(R.id.list);
listViewSlideAdapter=new ListViewSlideAdapter(this,list);
listView.setAdapter(listViewSlideAdapter);
listViewSlideAdapter.setOnClickListenerEditOrDelete(new ListViewSlideAdapter.OnClickListenerEditOrDelete() {
@Override
public void OnClickListenerEdit(int position) {
Toast.makeText(MainActivity.this, "edit position: " + position, Toast.LENGTH_SHORT).show();
}
@Override
public void OnClickListenerDelete(int position) {
Toast.makeText(MainActivity.this, "delete position: " + position, Toast.LENGTH_SHORT).show();
}
});
}
private void getData(){
for (int i=0;i<20;i++){
list.add(new String("第"+i+"个item"));
}
}
}