zoukankan      html  css  js  c++  java
  • 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:windowssystem32driversetc 复制完后enter一下,叫我雷锋就好了,Google,github正常使用啦不要忘记加群哦:Android&Go,Let's go! 521039620

    hosts下载地址:http://download.csdn.net/detail/onebelowzero2012/9359679

  • 相关阅读:
    结对-四则运算-最终程序
    结对- 四则运算器-结对项目总结
    课后作业-阅读任务-阅读提问-3
    课后作业-现代软件工程-阅读笔记
    软件工程课程总结
    团队-学生成绩管理一阶段互评
    结对-英文词频检测程序-测试过程
    团队-学生成绩管理-项目进度
    团队-学生成绩管理-模块开发过程
    eclipse下的文件路径问题
  • 原文地址:https://www.cnblogs.com/yizuochengchi2012/p/5050004.html
Copyright © 2011-2022 走看看