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

时间: 2024-10-25 17:59:56

android滑动删除的多种实现方式(一)的相关文章

Android数据加密概述及多种加密方式 聊天记录及账户加密 提供高质量的数据保护

Android数据加密概述及多种加密方式 聊天记录及账户加密 提供高质量的数据保护 数据加密又称密码学,它是一门历史悠久的技术,指通过加密算法和加密密钥将明文转变为密文,而解密则是通过解密算法和解密密钥将密文恢复为明文.数据加密目前仍是计算机系统对信息进行保护的一种最可靠的办法.它利用密码技术对信息进行加密,实现信息隐蔽,从而起到保护信息的安全的作用. 一.概述 数据加密是指通过加密算法和加密密钥将明文转变为密文,而解密则是通过解密算法和解密密钥将密文恢复为明文.它产生的历史相当久远,它是起源于

Android Activity切换动画多种实现方式与封装

关于Activity动画那些事 关于activity的动画,相信大家再熟悉不过了,我们开发中经常用到,网上资料也很多,但是也有一些小细节需要我们注意,今天这篇文章我总结了几种常用的动画实现方式,通过这篇文章,你可以了解到: 几种常见的activity动画实现方式 activity动画中需要注意的细节 这几种方式的优缺点比较,我们如何取舍 对这几种方式进行简易封装,提高我们的开发效率 几种常见的实现方式: 1. activity.overridePendingTransition() 这种方式相信

Android ListView 侧滑效果实现(滑动展开、滑动删除)

转载请注明出处:http://blog.csdn.net/lonelyroamer/article/details/42439875 项目需要ListView滑动删除的效果,首先肯定是拿来主义,在网上搜了一遍,发现这样的东西真不少,比较有名的Github上的SwipeListView.但是个人尝试了一下,发现它的bug不少,并且达不到我想要的效果.于是又尝试了一下其他的例子,发现基本效果都有,但是都有不少问题.要么事件冲突,要么OnItemListView或者某个Button响应不了.没办法,只

Android 实现用户列表信息滑动删除功能和选择删除功能

在项目开发过程中,常常需要对用户列表的信息进行删除的操作.Android中常用的删除操作方式有两种 ,一种就是类似微信的滑动出现删除按钮方式,还有一种是通过CheckBox进行选择,然后通过按钮进行删除的方式.本来的实例集成上述的两种操作方式来实现用户列表删除的效果. 设计思路:在适配器类MyAdapter一个滑动删除按钮显示或隐藏的Map,一个用于CheckBox是否选中的Map和一个与MainAcitivyt进行数据交互的接口ContentsDeleteListener,同时该接口包含两个方

Android Demo 下拉刷新+加载更多+滑动删除

小伙伴们在逛淘宝或者是各种app上,都可以看到这样的功能,下拉刷新和加载更多以及滑动删除,刷新,指刷洗之后使之变新,比喻突破旧的而创造出新的,比如在手机上浏览新闻的时候,使用下拉刷新的功能,我们可以第一时间掌握最新消息,加载更多是什么nie,简单来说就是在网页上逛淘宝的时候,我们可以点击下一页来满足我们更多的需求,但是在手机端就不一样了,没有上下页,怎么办nie,方法总比困难多,细心的小伙伴可能会发现,在手机端中,有加载更多来满足我们的要求,其实加载更多也是分页的一种体现.小伙伴在使用手机版QQ

ANDROID仿IOS微信滑动删除_SWIPELISTVIEW左滑删除例子

http://dwtedx.sinaapp.com/itshare_290.html 本例子实现了滑动删除ListView的Itemdemo的效果.大家都知道.这种创意是来源于IOS的.左滑删除的功能.在Android上面实现比较麻烦.本例子中不仅实现了左滑删除功能.还实现了左滑赞.左滑分享.左滑收藏等功能.当然大家也可以根据自己项目的需求来修改功能.QQ和微信也实现了相同的功能.大家可以看看.先上程序运行的效果 怎么样.大家看了这个截图是不是很心动呀.而且在左滑的时候还配有简单的滑动动画呢.非

【转】Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果

原文网址:http://blog.csdn.net/xiaanming/article/details/17539199 我在上一篇文章中Android 带你从源码的角度解析Scroller的滚动实现原理从源码的角度介绍了Scroller的滚动实现原理,相信大家对Scroller的使用有一定的了解,这篇文章就给大家带来使用Scroller的小例子,来帮助大家更加熟悉的掌握Scroller的使用,掌握好了Scroller的使用我们就能实现很多滑动的效果.例如侧滑菜单,launcher,ListVi

本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/18311877)Android 使用NineOldAndroids实现绚丽的ListView左右滑动删除Item效果

今天还是给大家带来自定义控件的编写,自定义一个ListView的左右滑动删除Item的效果,这个效果之前已经实现过了,有兴趣的可以看下Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果,之前使用的是滑动类Scroller来实现的,但是看了下通知栏的左右滑动删除效果,确实很棒,当我们滑动Item超过一半的时候,item的透明度就变成了0,我们就知道抬起手指的时候item就被删除了,当item的透明度不为0的时候,我们抬起手指Item会回到起始位置,这样我们就知道

android 继承ListView实现滑动删除功能.

在一些用户体验较好的应用上,可以经常遇见   在ListView中  向左或向右滑动便可删除那一项列表. 具体实现  则是继承ListView实现特定功能即可. (1). 新建 delete_button.xml文件 <?xml version="1.0" encoding="utf-8"?> <Button xmlns:android="http://schemas.android.com/apk/res/android" a