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

最近闲来无事,于是研究了一下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左右滑动的时候上下也会滑动,这个有待探索与改进,也希望大家提提意见,帮我改进!

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

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索android
ListView删除置顶
仿qq滑动删除listview、仿qq侧滑删除listview、listview置顶功能实现、listview item置顶、android listview置顶,以便于您获取更多的相关知识。

时间: 2024-10-31 12:45:33

Android仿QQ左滑删除置顶ListView操作_Android的相关文章

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

最近闲来无事,于是研究了一下qq的左滑删除效果,尝试着实现了一下,先上效果图: 大致思路原理: - 通过设置margin实现菜单的显示与隐藏 - 监听onTouchEvent,处理滑动事件 上代码 import android.content.Context; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.view.MotionEvent; import android.v

Android仿QQ长按删除弹出框功能示例

废话不说,先看一下效果图,如果大家感觉不错,请参考实现代码: 对于列表来说,如果想操作某个列表项,一般会采用长按弹出菜单的形式,默认的上下文菜单比较难看,而QQ的上下文菜单就人性化多了,整个菜单给用户一种气泡弹出的感觉,而且会显示在手指按下的位置,而技术实现我之前是使用popupWindow和RecyclerView实现的,上面一个RecyclerView,下面一个小箭头ImageView,但后来发现没有必要,而且可定制化也不高,还是使用多个TextView更好一点. 我封装了一下,只需要一个P

Android仿QQ列表滑动删除操作_Android

这篇山寨一个新版QQ的列表滑动删除,上篇有说到QQ的滑动删除,推测原理就是ListView本身每个item存在一个Button,只不过普通的状态下隐藏掉了,检测到向左的滑动事件的时候弹出隐藏的Button,不过再切换Button状态的时候会给Button一个出现和隐藏的动画.下面实现这个ListView.  首先有个难点就是通过ListView获取它某个item的View,对于ViewGroup,可以直接调用getChildAt()方法获取对应的子view,但是在ListView直接使用getC

Android仿QQ列表滑动删除操作

这篇山寨一个新版QQ的列表滑动删除,上篇有说到QQ的滑动删除,推测原理就是ListView本身每个item存在一个Button,只不过普通的状态下隐藏掉了,检测到向左的滑动事件的时候弹出隐藏的Button,不过再切换Button状态的时候会给Button一个出现和隐藏的动画.下面实现这个ListView. 首先有个难点就是通过ListView获取它某个item的View,对于ViewGroup,可以直接调用getChildAt()方法获取对应的子view,但是在ListView直接使用getCh

Android App中ListView仿QQ实现滑动删除效果的要点解析_Android

本来准备在ListView的每个Item的布局上设置一个隐藏的Button,当滑动的时候显示.但是因为每次只要存在一个Button,发现每个Item上的Button相互间不好控制.所以决定继承ListView然后结合PopupWindow. 首先是布局文件: delete_btn.xml:这里只需要一个Button <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=

Android仿QQ消息提示实现弹出式对话框_Android

本文在<7种形式的Android Dialog使用实例>在这篇文章的基础进行学习,具体内容如下 1.概述 android原生控件向来以丑著称(新推出的Material Design当另说),因此几乎所有的应用都会特殊定制自己的UI样式.而其中弹出式提示框的定制尤为常见,本篇我们将从模仿QQ退出提示框来看一下常见的几种自定义提示框的实现方式. 这里使用的几种弹出框实现方法概括为以下几种: 自定义Dialog 自定义PopupWindow 自定义Layout View Activity的Dialo

Android仿QQ好友列表实现列表收缩与展开_Android

ExpandableListView是一个垂直滚动显示两级列表项的视图,与ListView不同的是,它可以有两层:每一层都能够被独立的展开并显示其子项. 好友QQ列表,可以展开,可以收起,在android中,以往用的比较多的是listview,虽然可以实现列表的展示,但在某些情况下,我们还是希望用到可以分组并实现收缩的列表,那就要用到android的ExpandableListView,今天研究了一下这个的用法,也参考了很多资料动手写了一个小demo,实现了基本的功能,下面直接上效果图以及源代码

Android自定义组合控件之自定义下拉刷新和左滑删除实例代码_Android

绪论 最近项目里面用到了下拉刷新和左滑删除,网上找了找并没有可以用的,有比较好的左滑删除,但是并没有和下拉刷新上拉加载结合到一起,要不就是一些比较水的结合,并不能在项目里面使用,小编一着急自己组合了一个,做完了和QQ的对比了一下,并没有太大区别,今天分享给大家,其实并不难,但是不知道为什么网上没有比较好的Demo,当你的项目真的很急的时候,又没有比较好的Demo,那么"那条友谊的小船儿真是说翻就翻啊",好了,下面先来具体看一下实现后的效果吧:   代码已经上传到Github上了,小伙伴

Android仿QQ列表左滑删除操作_Android

最近学习了如何做一个像QQ的左滑RecyclerView的item显示选项的,主要是用到Scroller 我们首先新建一个自己的RecyclerView 定义好一些要用的的变量 重写构造方法,把前两个构造方法改为如下,使无论如何构造都要执行第三个构造方法 在第三个构造方法里初始化Scroller public class LeftSwipeMenuRecyclerView extends RecyclerView { //置顶按钮 private TextView tvTop; //删除按钮 p