实现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 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 int None = 0, Down = 1, Move = 2, Up = 3, Homing = 4;int state = None;}public BodyStatus bodyStatus = new BodyStatus();{public int None = 0, Left = 1, Right = 2, Homing_Left = 3, Homing_Right = 4;public int state = None;}public RemoveDirection removeDirection = new RemoveDirection();{public ListLoopCallback(OpenLooper openLooper) {openLooper.super();}(double ellapsedMillis) {if (bodyStatus.state == bodyStatus.Homing) {goHoming((float) ellapsedMillis);}}}(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() {() {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;(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”)(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;(RemoveListener removeListener) {this.mRemoveListener = removeListener;}{(RemoveDirection direction, int position);}public VelocityTracker velocityTracker;(MotionEvent event) {if (velocityTracker == null) {velocityTracker = VelocityTracker.obtain();}velocityTracker.addMovement(event);}() {if (velocityTracker != null) {velocityTracker.computeCurrentVelocity(1000);int velocity = (int) velocityTracker.getXVelocity();return velocity;}return 0;}() {if (velocityTracker != null) {velocityTracker.recycle();velocityTracker = null;}}}生命不在长而在于好,只要每一次尽力的演示,都值得鼓励与喝采。

实现ListView左右滑动删除和编辑(仿微信电话本)

相关文章:

你感兴趣的文章:

标签云: