个人习惯,先上图

 

android 滑动显示删除按钮 滑动删除怎么设置_ide

同事是个妹子(这点很重要),写滑动删除动能的时候用到了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正常使用啦