当前位置: 移动技术网 > IT编程>移动开发>Android > Android实现ListView左右滑动删除和编辑

Android实现ListView左右滑动删除和编辑

2019年07月24日  | 移动技术网IT编程  | 我要评论

有时候,为了实现项目中的需求,完成设计好的用户交互体验,不的不把这些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>

代码中用到的其他的类,在上一篇文章中有:

转载来自:

以上就是本文的全部内容,希望对大家的学习有所帮助。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网