当前位置: 代码迷 >> Android >> Android-实现ListView上下滑动删除和编辑(仿微信电话本)
  详细解决方案

Android-实现ListView上下滑动删除和编辑(仿微信电话本)

热度:109   发布时间:2016-04-28 01:13:57.0
Android-实现ListView左右滑动删除和编辑(仿微信电话本)

有时候,为了实现项目中的需求,完成设计好的用户交互体验,不的不把这些View重新改造成自己想要的效果。

Android原生的ListView是不支持左右滑动的,但是看到微信电话本上,联系人可以左右滑动进行操作的,就通过自己的设想和思路,并加以实现了。

思路:
1.获取到手指放到屏幕时的x,y位置,并判断点击的处于ListView的那个position。
2.判断滑动的方向,如果是上下方向,touch事件就交给ListView处理;如果是左右方向,就禁止ListView进行滑动。
3.根据手指的移动,来移动选中的View。
4.滑动结束后,把View归位。
5.通过传入的监听器,告诉用户是左滑动还是右滑动。

效果图:
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
重新的ListView的代码:

package com.example.wz.view;import android.annotation.SuppressLint;import android.content.Context;import android.os.Handler;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.VelocityTracker;import android.view.View;import android.view.ViewConfiguration;import android.view.WindowManager;import android.widget.AdapterView;import android.widget.ListView;import android.widget.TextView;import com.example.wz.R;import com.example.wz.util.MyLog;import com.example.wz.util.OpenLooper;import com.example.wz.util.OpenLooper.LoopCallback;public class MyListView extends ListView {    public MyLog log = new MyLog(this, true);    public float screenWidth;    public int mTouchSlop;    public float density;    public MyListView(Context context) {        super(context);    }    public MyListView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public float transleteSpeed = 2f;    public OpenLooper openLooper = null;    public LoopCallback loopCallback = null;    @SuppressWarnings("deprecation")    public MyListView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        this.screenWidth = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getWidth();        this.mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();        this.density = context.getResources().getDisplayMetrics().density;        this.openLooper = new OpenLooper();        this.openLooper.createOpenLooper();        this.loopCallback = new ListLoopCallback(this.openLooper);        this.openLooper.loopCallback = this.loopCallback;    }    public class BodyStatus {        public int None = 0, Down = 1, Move = 2, Up = 3, Homing = 4;        int state = None;    }    public BodyStatus bodyStatus = new BodyStatus();    public class RemoveDirection {        public int None = 0, Left = 1, Right = 2, Homing_Left = 3, Homing_Right = 4;        public int state = None;    }    public RemoveDirection removeDirection = new RemoveDirection();    public class ListLoopCallback extends LoopCallback {        public ListLoopCallback(OpenLooper openLooper) {            openLooper.super();        }        @Override        public void loop(double ellapsedMillis) {            if (bodyStatus.state == bodyStatus.Homing) {                goHoming((float) ellapsedMillis);            }        }    }    public void goHoming(float delta) {        float distance = (float) delta * transleteSpeed;        if (removeDirection.state == removeDirection.Left) {            float currentX = itemView.getScrollX() + distance;            if (currentX > screenWidth) {                distance = distance - (currentX - screenWidth);            }            itemView.scrollBy((int) (distance), itemView.getScrollY());            if (itemView.getScrollX() > screenWidth / 2 + 40 * screenWidth / 1080) {                t2.setTranslationX(itemView.getScrollX() - screenWidth / 2 - 40 * 3f);            } else {                t2.setTranslationX(40 * 3f);            }        } else if (removeDirection.state == removeDirection.Right) {            float currentX = itemView.getScrollX() - distance;            if (currentX < -screenWidth) {                distance = distance - (Math.abs(currentX) - screenWidth);            }            itemView.scrollBy((int) (-distance), itemView.getScrollY());            if (itemView.getScrollX() < -(screenWidth / 2 + 40 * 3f * 2)) {                t1.setTranslationX(-(Math.abs(itemView.getScrollX()) - screenWidth / 2 - 40 * 3f));            } else {                t1.setTranslationX(-40 * 3f);            }        } else if (removeDirection.state == removeDirection.Homing_Left) {            float currentX = itemView.getScrollX() - distance;            if (currentX < 0) {                distance = distance - (Math.abs(currentX));            }            itemView.scrollBy((int) (-distance), itemView.getScrollY());        } else if (removeDirection.state == removeDirection.Homing_Right) {            float currentX = itemView.getScrollX() + distance;            if (currentX > 0) {                distance = distance - currentX;            }            itemView.scrollBy((int) (distance), itemView.getScrollY());        }        if (itemView.getScrollX() == 0 || itemView.getScrollX() >= screenWidth || itemView.getScrollX() <= -screenWidth) {            openLooper.stop();            if (itemView.getScrollX() >= screenWidth) {                mRemoveListener.removeItem(removeDirection, position);            } else if (itemView.getScrollX() <= -screenWidth) {                mRemoveListener.removeItem(removeDirection, position);            }            new Handler().postDelayed(new Runnable() {                @Override                public void run() {                    itemView.scrollTo(0, itemView.getScrollY());                    bodyStatus.state = bodyStatus.None;                }            }, 300);        }    }    public int touch_down_x;    public int touch_down_y;    public View itemView;    public TextView t1;    public TextView t2;    public int SNAP_VELOCITY = 800;    public int position;    @Override    public boolean dispatchTouchEvent(MotionEvent event) {        int action = event.getAction();        if (action == MotionEvent.ACTION_DOWN) {            // addVelocityTracker(event);            if (bodyStatus.state != bodyStatus.None) {                return super.dispatchTouchEvent(event);            }            this.touch_down_x = (int) event.getX();            this.touch_down_y = (int) event.getY();            position = pointToPosition(touch_down_x, touch_down_y);            if (position == AdapterView.INVALID_POSITION) {                return super.dispatchTouchEvent(event);            }            itemView = getChildAt(position - getFirstVisiblePosition());            t2 = (TextView) itemView.findViewById(R.id.t2);            t1 = (TextView) itemView.findViewById(R.id.t1);        } else if (action == MotionEvent.ACTION_MOVE) {            if (Math.abs(getScrollVelocity()) > SNAP_VELOCITY || (Math.abs(event.getX() - touch_down_x) > mTouchSlop && Math.abs(event.getY() - touch_down_y) < mTouchSlop)) {                isSlide = true;            }        } else if (action == MotionEvent.ACTION_UP) {            int velocityX = getScrollVelocity();            if (Math.abs(velocityX) > SNAP_VELOCITY) {                if (velocityX > SNAP_VELOCITY) {                    bodyStatus.state = bodyStatus.Homing;                    removeDirection.state = removeDirection.Right;                    openLooper.start();                } else {                    bodyStatus.state = bodyStatus.Homing;                    removeDirection.state = removeDirection.Left;                    openLooper.start();                }            } else {                if (itemView.getScrollX() >= screenWidth / 2) {                    bodyStatus.state = bodyStatus.Homing;                    removeDirection.state = removeDirection.Left;                    openLooper.start();                } else if (itemView.getScrollX() <= -screenWidth / 2) {                    bodyStatus.state = bodyStatus.Homing;                    removeDirection.state = removeDirection.Right;                    openLooper.start();                } else {                    if (itemView.getScrollX() < 0) {                        removeDirection.state = removeDirection.Homing_Right;                    } else {                        removeDirection.state = removeDirection.Homing_Left;                    }                    bodyStatus.state = bodyStatus.Homing;                    openLooper.start();                }            }            recycleVelocityTracker();            isSlide = false;        }        return super.dispatchTouchEvent(event);    }    public boolean isSlide = false;    @SuppressLint("Recycle")    @Override    public boolean onTouchEvent(MotionEvent event) {        if (isSlide && position != AdapterView.INVALID_POSITION) {            requestDisallowInterceptTouchEvent(true);            addVelocityTracker(event);            int x = (int) event.getX();            int action = event.getAction();            if (action == MotionEvent.ACTION_DOWN) {            } else if (action == MotionEvent.ACTION_MOVE) {                MotionEvent cancelEvent = MotionEvent.obtain(event);                cancelEvent.setAction(MotionEvent.ACTION_CANCEL | (event.getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT));                onTouchEvent(cancelEvent);                int deltaX = touch_down_x - x;                touch_down_x = x;                if (itemView.getScrollX() > screenWidth / 2 + 40 * 3f * 2) {                    t2.setTranslationX(itemView.getScrollX() - screenWidth / 2 - 40 * 3f);                } else {                    t2.setTranslationX(40 * 3f);                }                if (itemView.getScrollX() < -(screenWidth / 2 + 40 * 3f * 2)) {                    t1.setTranslationX(-(Math.abs(itemView.getScrollX()) - screenWidth / 2 - 40 * 3f));                } else {                    t1.setTranslationX(-40 * 3f);                }                itemView.scrollBy(deltaX, 0);                return true;            }        }        return super.onTouchEvent(event);    }    public RemoveListener mRemoveListener;    public void setRemoveListener(RemoveListener removeListener) {        this.mRemoveListener = removeListener;    }    public interface RemoveListener {        public void removeItem(RemoveDirection direction, int position);    }    public VelocityTracker velocityTracker;    public void addVelocityTracker(MotionEvent event) {        if (velocityTracker == null) {            velocityTracker = VelocityTracker.obtain();        }        velocityTracker.addMovement(event);    }    public int getScrollVelocity() {        if (velocityTracker != null) {            velocityTracker.computeCurrentVelocity(1000);            int velocity = (int) velocityTracker.getXVelocity();            return velocity;        }        return 0;    }    public void recycleVelocityTracker() {        if (velocityTracker != null) {            velocityTracker.recycle();            velocityTracker = null;        }    }}

测试ListView的Activity代码:

package com.example.wz;import java.util.ArrayList;import android.app.Activity;import android.os.Bundle;import android.util.DisplayMetrics;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;import com.example.wz.view.MyListView;import com.example.wz.view.MyListView.RemoveDirection;import com.example.wz.view.MyListView.RemoveListener;public class TestListActivity extends Activity {    LayoutInflater mInflater;    @Override    protected void onCreate(Bundle savedInstanceState) {        displayMetrics = new DisplayMetrics();        this.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_testlist);        mInflater = getLayoutInflater();        listView = (MyListView) findViewById(R.id.slideCutListView);        showAddressDialog();    }    public DisplayMetrics displayMetrics;    MyListView listView;    public ArrayList<String> items;    public void showAddressDialog() {        items = new ArrayList<String>() {            {                add("item...1");                add("item...2");                add("item...3");                add("item...4");                add("item...5");                add("item...6");                add("item...7");                add("item...8");                add("item...9");                add("item...10");                add("item...11");                add("item...12");                add("item...13");                add("item...14");                add("item...15");                add("item...16");                add("item...17");                add("item...18");                add("item...19");                add("item...20");            }        };        NearbyRelationAdapter nearbyRelationAdapter = new NearbyRelationAdapter();        listView.setAdapter(nearbyRelationAdapter);        listView.setRemoveListener(new RemoveListener() {            @Override            public void removeItem(RemoveDirection direction, int position) {                if (direction.state == direction.Left) {                    Log.e("A", "left" + "-" + position);                } else if (direction.state == direction.Right) {                    Log.e("A", "right" + "-" + position);                }            }        });    }    public class NearbyRelationAdapter extends BaseAdapter {        @Override        public int getCount() {            return items.size();        }        @Override        public Object getItem(int posotion) {            return items.get(posotion);        }        @Override        public long getItemId(int posotion) {            return posotion;        }        @Override        public View getView(int position, View convertView, ViewGroup parent) {            Holder holder = null;            if (convertView == null) {                holder = new Holder();                convertView = mInflater.inflate(R.layout.view_menu_item1, null);                holder.title = (TextView) convertView.findViewById(R.id.title);                holder.o1 = convertView.findViewById(R.id.o1);                holder.o1.setTranslationX(-displayMetrics.widthPixels);                holder.o2 = convertView.findViewById(R.id.o2);                holder.o2.setTranslationX(displayMetrics.widthPixels);                convertView.setTag(holder);            } else {                holder = (Holder) convertView.getTag();            }            holder.title.setText(items.get(position));            convertView.scrollTo(0, convertView.getScrollY());            return convertView;        }        class Holder {            TextView title;            View o1, o2;        }    }}

ListView布局文件:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout 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:background="@android:color/darker_gray" >    <com.example.wz.view.MyListView        android:id="@+id/slideCutListView"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:cacheColorHint="@android:color/transparent"        android:listSelector="@android:color/transparent" >    </com.example.wz.view.MyListView>    <TextView        android:layout_width="1dp"        android:layout_height="match_parent"        android:layout_centerHorizontal="true"        android:background="#0099cd" /></RelativeLayout>

ListView 的Item布局:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:background="#fff" >    <RelativeLayout        android:id="@+id/o1"        android:layout_width="match_parent"        android:layout_height="60dp"        android:background="#ff0000" >        <TextView            android:id="@+id/t1"            android:layout_width="80dp"            android:layout_height="wrap_content"            android:layout_alignParentRight="true"            android:layout_centerVertical="true"            android:gravity="center"            android:padding="10dp"            android:text="删除"            android:textColor="#99000000"            android:textSize="18sp" />    </RelativeLayout>    <RelativeLayout        android:id="@+id/o2"        android:layout_width="match_parent"        android:layout_height="60dp"        android:background="#660099cd" >        <TextView            android:id="@+id/t2"            android:layout_width="80dp"            android:layout_height="wrap_content"            android:layout_alignParentLeft="true"            android:layout_centerVertical="true"            android:gravity="center"            android:padding="10dp"            android:text="编辑"            android:textColor="#99000000"            android:textSize="18sp" />    </RelativeLayout>    <RelativeLayout        android:id="@+id/r1"        android:layout_width="match_parent"        android:layout_height="60dp"        android:background="#fff" >        <TextView            android:id="@+id/title"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_centerVertical="true"            android:gravity="center_vertical"            android:textColor="#99000000"            android:textSize="18sp" />    </RelativeLayout></RelativeLayout>

代码中用到的其他的类,在上一篇文章中有:
http://blog.csdn.net/qxs965266509/article/details/45200289

如有转载请著名来自http://blog.csdn.net/qxs965266509

3楼u010785685昨天 21:48
学习了,感谢楼主的分享
2楼qq_27836885昨天 19:20
支持
1楼qxs965266509昨天 17:50
谢谢。
  相关解决方案