热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

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

这篇文章主要为大家详细介绍了Android仿QQ左滑删除置顶ListView操作,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

最近闲来无事,于是研究了一下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 = 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文件定义如下:

<&#63;xml version="1.0" encoding="utf-8"&#63;>


 

  
 

 

  

  
 

最后就是删除操作与置顶操作,这个就比较简单,给按钮添加点击事件即可。我是在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左右滑动的时候上下也会滑动,这个有待探索与改进,也希望大家提提意见,帮我改进!

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


推荐阅读
  • ServletContext接口在Java Web开发中扮演着重要角色,它提供了一种方式来获取关于整个Web应用程序的信息。通过ServletContext,开发者可以访问初始化参数、共享数据以及应用资源。 ... [详细]
  • Eclipse 中 JSP 开发环境配置指南
    本文详细介绍了如何在 Eclipse 集成开发环境中配置 JSP 运行环境,包括必要的软件下载、Tomcat 服务器的配置以及常见问题的解决方法。 ... [详细]
  • 本文探讨如何利用Java反射技术来模拟Webwork框架中的URL解析过程。通过这一实践,读者可以更好地理解Webwork及其后续版本Struts2的工作原理,尤其是它们在MVC架构下的角色。 ... [详细]
  • 本文探讨了Web开发与游戏开发之间的主要区别,旨在帮助开发者更好地理解两种开发领域的特性和需求。文章基于作者的实际经验和网络资料整理而成。 ... [详细]
  • 本文详细介绍了如何在Android应用中使用GridView组件以网格形式展示数据(如文本和图像)。通过行列布局,实现类似矩阵的数据展示效果。 ... [详细]
  • 在使用Maven进行项目构建时,由于依赖库的下载速度慢常常让人感到沮丧,这直接影响了开发效率和学习热情。幸运的是,阿里云提供了一个快速的国内镜像服务,能够显著提升Maven项目的构建速度。 ... [详细]
  • 本文介绍了在Android项目中实现时间轴效果的方法,通过自定义ListView的Item布局和适配器逻辑,实现了动态显示和隐藏时间标签的功能。文中详细描述了布局文件、适配器代码以及时间格式化工具类的具体实现。 ... [详细]
  • Android中实现复合旋转动画效果
    本文将探讨如何在Android应用中实现动态且吸引人的旋转动画。通过结合多种动画类型,如透明度变化、旋转、缩放和位移,可以创造出更为复杂的视觉效果。我们将从XML布局和Java代码两个方面进行详细介绍。 ... [详细]
  • Android商城应用开发指南(第二部分):创建启动欢迎页
    大多数商城应用程序在启动时会显示一个欢迎页面,以提升用户体验。本文将指导您如何实现一个基本的欢迎页,该页面会在用户打开应用后短暂展示,随后自动跳转至主界面。 ... [详细]
  • 详解 | 日志系统ViseLog的基本使用与功能
    本文详细介绍了日志系统ViseLog的使用方法及其核心功能,旨在帮助开发者更好地理解和利用这一工具,提高开发效率。 ... [详细]
  • 本文探讨了使用Filter作为控制器的优势,以及Servlet与Filter之间的主要差异。同时,详细解析了Servlet的工作流程及其生命周期,以及ServletConfig与ServletContext的区别与应用场景。 ... [详细]
  • Android中解析XML文件的实践指南
    本文详细介绍了在Android应用开发中解析XML文件的方法,包括从本地文件和网络资源获取XML文件的不同途径,以及使用DOM、SAX和PULL三种解析方式的具体实现。 ... [详细]
  • 在使用Maven构建多模块项目时,执行`nvm clean install`命令可能会遇到子模块路径配置错误的问题,导致提示‘pom.xml does not exist’的错误信息。 ... [详细]
  • 本文详细介绍了如何使用 PHP 编程语言输出 99 乘法表,包括使用不同的循环结构如 do-while、for 循环等方法,并提供了具体的代码示例。 ... [详细]
  • Java EE CDI:解决依赖关系冲突的实例
    在本教程中,我们将探讨如何在Java EE的CDI(上下文和依赖注入)框架中有效解决依赖关系的冲突问题。通过学习如何使用限定符,您将能够为应用程序的不同客户端提供多种接口实现,并确保每个客户端都能正确调用其所需的实现。 ... [详细]
author-avatar
静静敲代码
很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有