欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2024-03-02 15:24:58
有时候,为了实现项目中的需求,完成设计好的用户交互体验,不的不把这些view重新改造成自己想要的效果。 android原生的listview是不支持左右滑动的,但是看到微...

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

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

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

效果图:

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

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

重新的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>

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

转载来自:

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