当前位置: 移动技术网 > IT编程>移动开发>Android > Android仿QQ左滑删除置顶ListView操作

Android仿QQ左滑删除置顶ListView操作

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

罗定旅游景点大全,安家网 上海,mykeylock

最近闲来无事,于是研究了一下qq的左滑删除效果,尝试着实现了一下,先上效果图:

大致思路原理:
- 通过设置margin实现菜单的显示与隐藏
- 监听ontouchevent,处理滑动事件

上代码

import android.content.context;
import android.util.attributeset;
import android.util.displaymetrics;
import android.view.motionevent;
import android.view.viewgroup;
import android.view.windowmanager;
import android.widget.linearlayout;
import android.widget.listview;

/**
 * created by mooreli on 2016/8/8.
 */
public class slidelistview extends listview {
  private string tag = getclass().getsimplename();

  private int mscreenwidth;
  private int mdownx;
  private int mdowny;
  private int mmenuwidth;

  private boolean ismenushow;
  private boolean ismoving;

  private int moperateposition = -1;
  private viewgroup mpointchild;
  private linearlayout.layoutparams mlayoutparams;

  public slidelistview(context context) {
    super(context);
    getscreenwidth(context);
  }

  public slidelistview(context context, attributeset attrs) {
    super(context, attrs);
    getscreenwidth(context);
  }

  public slidelistview(context context, attributeset attrs, int defstyleattr) {
    super(context, attrs, defstyleattr);
    getscreenwidth(context);
  }

  private void getscreenwidth(context context) {
    windowmanager manager = (windowmanager) context.getsystemservice(context.window_service);
    displaymetrics dm = new displaymetrics();
    manager.getdefaultdisplay().getmetrics(dm);
    mscreenwidth = dm.widthpixels;
  }

  @override
  public boolean ontouchevent(motionevent ev) {
    switch (ev.getaction()) {
      case motionevent.action_down:
        performactiondown(ev);
        break;
      case motionevent.action_move:
        performactionmove(ev);
        break;
      case motionevent.action_up:
        performactionup();
        break;
    }
    return super.ontouchevent(ev);
  }

  private void performactiondown(motionevent ev) {
    mdownx = (int) ev.getx();
    mdowny = (int) ev.gety();
    //如果点击的不是同一个item,则关掉正在显示的菜单
    int position = pointtoposition(mdownx, mdowny);
    if (ismenushow && position != moperateposition) {
      turntonormal();
    }
    moperateposition = position;
    mpointchild = (viewgroup) getchildat(position - getfirstvisibleposition());
    if (mpointchild != null) {
      mmenuwidth = mpointchild.getchildat(1).getlayoutparams().width;
      mlayoutparams = (linearlayout.layoutparams) mpointchild.getchildat(0).getlayoutparams();
      mlayoutparams.width = mscreenwidth;
      setchildlayoutparams();
    }
  }

  private boolean performactionmove(motionevent ev) {
    int nowx = (int) ev.getx();
    int nowy = (int) ev.gety();
//    if (ismoving) {
//      if (math.abs(nowy - mdowny) > 0) {
//        log.e(tag, "kkkkkkk");
//        onintercepttouchevent(ev);
//      }
//    }
    if (math.abs(nowx - mdownx) > 0) {
      //左滑 显示菜单
      if (nowx < mdownx) {
        if (ismenushow) {
          mlayoutparams.leftmargin = -mmenuwidth;
        } else {
          //计算显示的宽度
          int scroll = (nowx - mdownx);
          if (-scroll >= mmenuwidth) {
            scroll = -mmenuwidth;
          }
          mlayoutparams.leftmargin = scroll;
        }
      }
      //右滑 如果菜单显示状态,则关闭菜单
      if (ismenushow && nowx > mdownx) {
        int scroll = nowx - mdownx;
        if (scroll >= mmenuwidth) {
          scroll = mmenuwidth;
        }
        mlayoutparams.leftmargin = scroll - mmenuwidth;
      }
      setchildlayoutparams();
      ismoving = true;
      return true;
    }

    return super.ontouchevent(ev);
  }

  private void performactionup() {
    //超过一半时,显示菜单,否则隐藏
    if (-mlayoutparams.leftmargin >= mmenuwidth / 2) {
      mlayoutparams.leftmargin = -mmenuwidth;
      setchildlayoutparams();
      ismenushow = true;
    } else {
      turntonormal();
    }
    ismoving = false;
  }

  private void setchildlayoutparams(){
    if(mpointchild != null){
      mpointchild.getchildat(0).setlayoutparams(mlayoutparams);
    }
  }

  /**
   * 正常显示
   */
  public void turntonormal() {
    mlayoutparams.leftmargin = 0;
    moperateposition = -1;
    setchildlayoutparams();
    ismenushow = false;
  }
}

item的布局要注意,因为在自定义view中写死的是获取第一个子布局为显示内容,所以需要将显示的样式写在一个容器中,将菜单写在另一个容器中,两个平行的关系。
xml文件定义如下:

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:background="#ffffff"
  android:orientation="horizontal">

  <linearlayout
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:orientation="horizontal">

    <textview
      android:id="@+id/main_tv_title"
      android:layout_width="wrap_content"
      android:layout_height="match_parent"
      android:layout_marginleft="10dp"
      android:gravity="center_vertical"
      android:textsize="18sp" />
  </linearlayout>

  <linearlayout
    android:layout_width="180dp"
    android:layout_height="60dp"
    android:orientation="horizontal">

    <textview
      android:id="@+id/main_tv_delete"
      android:layout_width="0dp"
      android:layout_height="match_parent"
      android:layout_weight="1"
      android:background="#ff0000"
      android:gravity="center"
      android:text="删除"
      android:textcolor="#ffffff" />

    <textview
      android:id="@+id/main_tv_top"
      android:layout_width="0dp"
      android:layout_height="match_parent"
      android:layout_weight="1"
      android:background="#dfcdbf"
      android:gravity="center"
      android:text="置顶"
      android:textcolor="#ffffff" />
  </linearlayout>
</linearlayout>

最后就是删除操作与置顶操作,这个就比较简单,给按钮添加点击事件即可。我是在adapter中定义实现,记得操作后要将菜单关掉!

上部分代码: 

    holder.tvtitle.settext(minfos.get(position));
    holder.tvdelete.setonclicklistener(new view.onclicklistener() {
      @override
      public void onclick(view v) {
        minfos.remove(position);
        notifydatasetchanged();
        mlistview.turntonormal();
      }
    });
    holder.tvtop.setonclicklistener(new view.onclicklistener() {
      @override
      public void onclick(view v) {
        string temp = minfos.get(position);
        minfos.remove(position);
        minfos.add(0, temp);
        notifydatasetchanged();
        mlistview.turntonormal();
      }
    });

最后还有一个遗留问题,listview左右滑动的时候上下也会滑动,这个有待探索与改进,也希望大家提提意见,帮我改进!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

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

相关文章:

验证码:
移动技术网