android滑动删除的多种实现方式(一)
个人习惯,先上图

同事是个妹子(这点很重要),写滑动删除动能的时候用到了SwipeLayout,然后悲催的是,滑动时间被拦截了,解决方法先不提,在(一)中先讲解SwipeLayout下载listview并实现滑动删除效果,当然加载listview有很多种方式,后面都会讲到,
首先你需要了解ViewDragHelper,ViewDragHelper重写触摸事件参数从而可以拖动改变子view的位置,具体魅力见:
需要看源码的关联一下http://www.tuicool.com/articles/JZbEvya
2013年谷歌i/o大会上介绍了两个新的layout: SlidingPaneLayout和DrawerLayout都用到viewdragHelper处理拖动事件,好了话不多费能力有限精力不充足不研究太深,会用就ok,具体见滑动删除例子代码:
》》》创建SwipeLayout
package com.one.swipe;
import android.content.Context;
import android.graphics.Rect;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
/**
 * 相当于继承viewGroup
 */
public class SwipeLayout extends FrameLayout {
/**
	 * 用到枚举三种状态,代码模式
	 */
	public static enum Status {
		Close, Open, Swiping
	}
public interface OnSwipeListener{
		void onClose(SwipeLayout layout);
		void onOpen(SwipeLayout layout);
void onStartOpen(SwipeLayout layout);
		void onStartClose(SwipeLayout layout);
	}
private Status status = Status.Close;
	private OnSwipeListener onSwipeListener;
public Status getStatus() {
		return status;
	}
public void setStatus(Status status) {
		this.status = status;
	}
public OnSwipeListener getOnSwipeListener() {
		return onSwipeListener;
	}
public void setOnSwipeListener(OnSwipeListener onSwipeListener) {
		this.onSwipeListener = onSwipeListener;
	}
//--------------------------上面和我们常用设置adapter差不多绑定侦听和布局设置参数
	private ViewDragHelper mHelper;
public SwipeLayout(Context context) {
		this(context, null);
	}
public SwipeLayout(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}
public SwipeLayout(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
// 1. 创建ViewDragHelper  第二个参数默认值 
		mHelper = ViewDragHelper.create(this,1.0f, callback);
	}
// 3. 重写一系列回调的方法
	ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {
@Override
		public boolean tryCaptureView(View child, int pointerId) {
			return true;
		}
/**
		 * 水平方向移动的处理 限制范围
		 */
		public int getViewHorizontalDragRange(View child) {
			return mRange;
		};
		/**
		 * 竖直方向的处理
		 */
		public int clampViewPositionHorizontal(View child, int left, int dx) {
			// 返回的值决定了将要移动到的位置.
			if(child == mFrontView){
				if(left < - mRange){
					// 限定左范围
					return - mRange;
				}else if (left > 0) {
					// 限定右范围
					return 0;
				}
			}else if (child == mBackView) {
				if(left < mWidth - mRange){
					// 限定左范围
					return mWidth - mRange;
				}else if (left > mWidth) {
					// 限定右范围
					return mWidth;
				}
			}
			return left;
		};
// 位置发生改变的时候, 把水平方向的偏移量传递给另一个布局
		public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
			if(changedView == mFrontView){
				// 拖拽的是前布局,  把刚刚发生的 偏移量dx 传递给 后布局
				mBackView.offsetLeftAndRight(dx);
			} else if (changedView == mBackView) {
				// 拖拽的是后布局,  把刚刚发生的 偏移量dx 传递给 前布局
				mFrontView.offsetLeftAndRight(dx);
			}
dispatchDragEvent();
invalidate();
		};
		/**
		 * Released svn上貌似有这个设置,回滚
		 */
		public void onViewReleased(View releasedChild, float xvel, float yvel) {
			// 松手时候会被调用
			// xvel 向右+, 向左-
			if(xvel == 0 && mFrontView.getLeft() < - mRange * 0.5f){
				open();
			}else if(xvel < 0){
				open();
			}else {
				close();
			}
		};
	};
	private View mBackView;
	private View mFrontView;
	private int mRange;
	private int mWidth;
	private int mHeight;
/**
	 * 更新当前的状态
	 */
	protected void dispatchDragEvent() {
Status lastStatus = status;
		// 获取最新的状态
		status = updateStatus();
// 状态改变的时候, 调用监听里的方法
		if(lastStatus != status && onSwipeListener != null){
			if(status == Status.Open){
				onSwipeListener.onOpen(this);
			}else if (status == Status.Close) {
				onSwipeListener.onClose(this);
			}else if (status == Status.Swiping) {
				if(lastStatus == Status.Close){
					onSwipeListener.onStartOpen(this);
				}else if (lastStatus == Status.Open) {
					onSwipeListener.onStartClose(this);
				}
			}
		}
}
private Status updateStatus() {
		int left = mFrontView.getLeft();
		if(left == 0){
			return Status.Close;
		}else if (left == -mRange) {
			return Status.Open;
		}
return Status.Swiping;
	}
@Override
	public void computeScroll() {
		super.computeScroll();
		// 维持平滑动画继续
		if(mHelper.continueSettling(true)){
			ViewCompat.postInvalidateOnAnimation(this);
		}
	}
/**
	 * 关闭
	 */
	protected void close() {
		close(true);
	}
	public void close(boolean isSmooth){
int finalLeft = 0;
		if(isSmooth){
			// 触发平滑动画
			if(mHelper.smoothSlideViewTo(mFrontView, finalLeft, 0)){
				ViewCompat.postInvalidateOnAnimation(this);
			}
}else {
			layoutContent(false);
		}
	}
/**
	 * 打开
	 */
	protected void open() {
		open(true);
	}
	public void open(boolean isSmooth){
int finalLeft = -mRange;
		if(isSmooth){
			// 触发平滑动画
			if(mHelper.smoothSlideViewTo(mFrontView, finalLeft, 0)){
				ViewCompat.postInvalidateOnAnimation(this);
			}
}else {
			layoutContent(false);
		}
	}
	// 2. 转交触摸事件拦截判断, 处理触摸事件
		public boolean onInterceptTouchEvent(android.view.MotionEvent ev) {
			 if (mHelper.shouldInterceptTouchEvent(ev)) {
		            return true;
		    }
		    return super.onInterceptTouchEvent(ev);
		};
	/**
	 * 时间交由mHelper处理,默认返回true
	 */
	@Override
	public boolean onTouchEvent(MotionEvent event) {
try {
			mHelper.processTouchEvent(event);
		} catch (Exception e) {
			e.printStackTrace();
		}
return true;
	}
@Override
	protected void onLayout(boolean changed, int left, int top, int right,
			int bottom) {
		super.onLayout(changed, left, top, right, bottom);
// 默认是关闭状态
		layoutContent(false);
	}
/**
	 * 根据当前的开启状态摆放内容
	 * @param isOpen
	 */
	private void layoutContent(boolean isOpen) {
		// 设置前布局位置
		Rect rect = computeFrontRect(isOpen);
		mFrontView.layout(rect.left, rect.top, rect.right, rect.bottom);
		// 根据前布局位置设置后布局位置
		Rect backRect = computeBackRectViaFront(rect);
		mBackView.layout(backRect.left, backRect.top, backRect.right, backRect.bottom);
// 把任意布局顺序调整到最上
		bringChildToFront(mFrontView);
	}
/**
	 * 计算后布局的矩形区域
	 * @param rect
	 * @return
	 */
	private Rect computeBackRectViaFront(Rect rect) {
		int left = rect.right;
		return new Rect(left, 0, left + mRange , 0 + mHeight);
	}
/**
	 * 计算前布局的矩形区域
	 * @param isOpen
	 * @return
	 */
	private Rect computeFrontRect(boolean isOpen) {
		int left = 0;
		if(isOpen){
			left = -mRange;
		}
		return new Rect(left, 0, left + mWidth, 0 + mHeight);
	}
@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
mRange = mBackView.getMeasuredWidth();
		mWidth = getMeasuredWidth();
		mHeight = getMeasuredHeight();
}
	/**
	 * 赋值等一些操作
	 */
	@Override
	protected void onFinishInflate() {
		super.onFinishInflate();
mBackView = getChildAt(0);
		mFrontView = getChildAt(1);
	}
/**
	 * 这个方法可以用来设置拖动距离等操作
	 */
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		// TODO Auto-generated method stub
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
============================================================
package com.one.swipe;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.one.swipe.SwipeLayout.OnSwipeListener;
public class MyAdapter extends BaseAdapter {
	private Context context;
	private List<String> list;
	private ArrayList<SwipeLayout> openedItems;
public MyAdapter(Context context, List<String> list) {
		super();
		this.context=context;
		this.list=list;
		openedItems = new ArrayList<SwipeLayout>();
	}
	@Override
	public int getCount() {
		return list==null?0:list.size();
	}
@Override
	public Object getItem(int position) {
		return list == null ? 0 : position;
	}
@Override
	public long getItemId(int position) {
		return 0;
	}
@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder holder;
		if(convertView==null){
			holder = new ViewHolder();
			convertView=View.inflate(context, R.layout.public_type_item, null);
			holder.tv_type=(TextView) convertView.findViewById(R.id.tv_type);
			holder.tv_date=(TextView) convertView.findViewById(R.id.tv_date);
			holder.tv_price=(TextView) convertView.findViewById(R.id.tv_price);
		    convertView.setTag(holder);
		}else{
			holder=(ViewHolder) convertView.getTag();
		}
          SwipeLayout sl = (SwipeLayout)convertView;
sl.setOnSwipeListener(new OnSwipeListener() {
@Override
			public void onClose(SwipeLayout layout) {
				openedItems.remove(layout);
			}
@Override
			public void onOpen(SwipeLayout layout) {
				openedItems.add(layout);
			}
@Override
			public void onStartOpen(SwipeLayout layout) {
				// 关闭所有已经打开的条目
				for (int i = 0; i < openedItems.size(); i++) {
					openedItems.get(i).close(true);
				}
openedItems.clear();
			}
@Override
			public void onStartClose(SwipeLayout layout) {
			}
});
String  tv_type=holder.tv_type.getText().toString().trim();
        List<String> list = new ArrayList<String>();
        list.add(tv_type);
		 return convertView;
	}
	class  ViewHolder{
		public TextView tv_type;
		public TextView tv_date;
		public TextView tv_price;
	}
}
====================================
MainActivity
package com.one.swipe;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
public class MainActivity extends Activity implements OnClickListener {
private Button btn;
	private ListView view;
	private List<String> list;
	private MyAdapter adapter;
	private EditText et;
@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.btn);
		btn.setOnClickListener(this);
		view = (ListView) findViewById(R.id.listview);
		et = (EditText) findViewById(R.id.et);
initData();
	}
private void initData() {
		list = new ArrayList();
		for (int i = 0; i < 3; i++) {
			list.add(i + "");
		}
}
@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.btn:
adapter = new MyAdapter(getApplicationContext(), list);
			view.setAdapter(adapter);
			adapter.notifyDataSetChanged();
break;
default:
			break;
		}
	}
}
================================
main.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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"
    android:scrollbars="vertical" >
<LinearLayout
	    android:layout_width="match_parent"
	    android:layout_height="match_parent"
	    android:orientation="vertical"
	    >
<EditText 
	        android:id="@+id/et"
	        android:layout_width="match_parent"
	        android:layout_height="40dp"
	       	android:layout_gravity="center_horizontal"
	       	android:text="写点啥呢"
	        />
	    <Button
	        android:layout_marginTop="20dp"
	        android:id="@+id/btn"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:text="看效果" 
	        android:layout_centerInParent="true"
	        android:layout_gravity="center"
	        />
	    <ListView 
	        android:id="@+id/listview"
	        android:layout_width="fill_parent"
	        android:layout_height="120dp"
	        android:layout_marginTop="20dp"
	        />
</LinearLayout>
</ScrollView>
============================
item.xml
<?xml version="1.0" encoding="utf-8"?>
<com.one.swipe.SwipeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/sl"
    android:layout_width="match_parent"
    android:layout_height="@dimen/item_height" >
     <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="@dimen/item_height"
        android:orientation="horizontal" >
<TextView
            android:layout_width="60dp"
            android:layout_height="@dimen/item_height"
            android:background="#666666"
            android:gravity="center"
            android:text="cancel"
            android:textColor="#FFFFFF" />
<TextView
            android:layout_width="60dp"
            android:layout_height="@dimen/item_height"
            android:background="#FF0000"
            android:gravity="center"
            android:text="Delete"
            android:textColor="#FFFFFF" />
    </LinearLayout>
<LinearLayout 
    android:layout_width="match_parent"
    android:layout_height="@dimen/item_height"
    android:background="@drawable/bg_detail_item"
    android:orientation="horizontal"
     >
<TextView
        android:id="@+id/tv_type"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_weight="1"
        android:gravity="center"
        android:hint="做平凡一个"
        android:textColor="@color/txt_date"
        android:textSize="@dimen/text_size" />
<TextView
        android:id="@+id/tv_date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_weight="1"
        android:gravity="center"
        android:hint="用十倍苦心"
        android:textColor="@color/txt_date"
        android:textSize="@dimen/text_size" />
<TextView
        android:id="@+id/tv_price"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_weight="1"
        android:gravity="center"
        android:hint="一座城池2012"
        android:textColor="@color/txt_date"
        android:textSize="@dimen/text_size" />
</LinearLayout>
</com.one.swipe.SwipeLayout>
ok,就是这些了 还有5个关于ViewDragHelper有简单到难的demo整理完了,明天在一块上传吧,
hosts 文件配置c:\windows\system32\drivers\etc 复制完后enter一下,叫我雷锋就好了,Google,github正常使用啦不要忘记加群哦:Android&Go,Let's go! 521039620
hosts下载地址:http://download.csdn.net/detail/onebelowzero2012/9359679
android滑动删除的多种实现方式(一)的更多相关文章
- Android数据加密概述及多种加密方式 聊天记录及账户加密 提供高质量的数据保护
		Android数据加密概述及多种加密方式 聊天记录及账户加密 提供高质量的数据保护 数据加密又称password学,它是一门历史悠久的技术,指通过加密算法和加密密钥将明文转变为密文.而解密则是通过解密 ... 
- Android滑动删除功能
		今天学习了新的功能那就是滑动删除数据.先看一下效果 我想这个效果大家都很熟悉吧.是不是在qq上看见过这个效果.俗话说好记性不如赖笔头,为了我的以后,为了跟我一样自学的小伙伴们,我把我的代码粘贴在下面. ... 
- Android 滑动删除控件推荐
		implementation 'com.github.mcxtzhang:SwipeDelMenuLayout:V1.3.0' <?xml version="1.0" enc ... 
- Android 用HorizontalScrollView实现ListView的Item滑动删除 ,滑动错乱 冲突
		用HorizontalScrollView实现类似微信的滑动删除 测试于:Android2.2+ 对于Android来说按键操作已经在减少,越来越多的手势操作层出不穷,今天介绍一款LIstView的I ... 
- 【转】Android 实现ListView的滑动删除效果
		http://www.cnblogs.com/weixiao870428/p/3524055.html http://download.csdn.net/download/love_javc_you/ ... 
- Android Demo 下拉刷新+加载更多+滑动删除
		小伙伴们在逛淘宝或者是各种app上,都可以看到这样的功能,下拉刷新和加载更多以及滑动删除,刷新,指刷洗之后使之变新,比喻突破旧的而创造出新的,比如在手机上浏览新闻的时候,使用下拉刷新的功能,我们可以第 ... 
- Android开发学习之路-RecyclerView滑动删除和拖动排序
		Android开发学习之路-RecyclerView使用初探 Android开发学习之路-RecyclerView的Item自定义动画及DefaultItemAnimator源码分析 Android开 ... 
- android QQ消息左滑动删除实例(优化版SwipeListViewEX)
		仿 QQ消息左滑动删除item消息实例 源代码参考:http://blog.csdn.net/gaolei1201/article/details/42677951 自己作了一些调整,全部代码下载地址 ... 
- Android 使用NineOldAndroids实现绚丽的ListView左右滑动删除Item效果
		本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/18311877) 今天还是给大家带来自定义控件的编写,自定义一个Lis ... 
随机推荐
- win7 iis7.5 配置错误解决办法
			win7 iis7.5 配置HTTP 错误 404.3 在初次使用IIS7的时候经常遇到的一个错误解决办法1: 找到Visual Studio命令提示工具,运行aspnet_regiis.exe -i ... 
- C#网页版计算器程序代码
			calculator.aspx.cs代码 using System; using System.Collections.Generic; using System.Linq; using System ... 
- 通过html5的range属性动态改变图片的大小
			range属性已经是很成熟的属性了,我们可以使用这个属性进行动态调整图片的宽度,其中原理在于通过不断获取range的值,并赋予给所需要的图片,进而达到动态改变图片的效果.下面贴出具体的代码,主要参照了 ... 
- Codevs 1337 银行里的迷宫
			1337 银行里的迷宫 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 白银 Silver 传送门 题目描述 Description 楚楚每一次都在你的帮助下过了一关又一关(比如他开 ... 
- [Introduction to programming in Java 笔记] 1.3.7 Converting to binary 十进制到二进制的转换
			public class Binary { public static void main(String[] args) { // Print binary representation of N. ... 
- leetcode中一些要用到动态规划的题目
			需要仔细回顾的题目: 1.Interleaving String 交叉存取字符串 2.Decode Ways 字符串解码 3.Subsets Subsets II 求一个 ... 
- 忘记Mysql的root密码怎么办?
			解决方法: 1.打开cmd,用net start命令查看是否开启了mysql服务,如果开启,用net stop mysql 命令关闭mysql 2.进入mysql的安装目录下的bin目录,例如:E:\ ... 
- red bottom shoes featured
			最近做了一个红底高根鞋的电商网站 Cheap Red Bottom Shoes Christian Louboutin Loafers Bestsellers Christian Louboutin ... 
- C++ 中的权限控制
			权限控制,指的是用户只能访问符合自己权限的资源,系统对用户进行权限控制以防止用户的误操作/恶意操作等. 在C++代码中,权限控制指的是程序员在接口声明/类声明/函数声明等中进行的授权控制.如下面的代码 ... 
- 【原创】Android 从一个Activity跳转到另外一个Activity
			Android四大组件activity使用,实现两个activity之间的跳转 基本流程:创建两个activity-将其中一个activity中组件作为事件源-通过组件事件的处理借助intent对象实 ... 
