android 侧滑删除功能,200行代码让你在Android中完美实现iOS版侧滑删除效果

使用几个月的IOS之后,发现IOS中侧滑删除俺就

大家好,自己开始学习Android已经差不多半年了吧,前前后后看了不少的博客获益匪浅。渐渐的随着技术的提升,慢慢感觉网上其它的一些功能的实现又不是那么完美,今天就给大家带来一篇在Android中完全仿照IOS侧滑删除的效果。

首先我们来看一下实现的效果如何:

6ec4ec082dd1092543954be7fc918af2.gif           

28f350c5c7dce6c42d3303e871801d99.gif

第一张图片是展示删除的效果,删除时会有上缩动画效果

第二张图片是展示滑出删除按钮时的事件抢占,有删除按钮存在时需要抢占掉ListView的滑动事件,而且保证至多有1个删除按钮显示

所以说实现完美的侧滑删除效果需要了解Android中的事件分发机制,如果有不明白的同学可以去

郭神:

鸿前辈:

这两位前辈的博客里看事件分发章节的内容。

好了我们废话不多说,进入主题。

本例的侧滑删除用的是HorizontalScrollView来实现的。

首先我们先创建我们的activity_main.xml,主布局文件

xmlns:tools=""

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="com.example.horizontalslidelistview.MainActivity" >

android:id="@+id/listview"

android:layout_width="match_parent"

android:layout_height="wrap_content"

/>

是不是很简单,仅仅是只有一个自定义的ListView,不过我们先放过这个自定义的ListVIew,再来看看ListView中item的布局文件

item_horizontal_slide_listview.xml

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:scrollbars="none" >

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:orientation="horizontal" >

android:id="@+id/item_text"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:gravity="center_vertical"

android:background="#EEEEEE"

android:paddingLeft="20dp"

android:textColor="#FF0000"

android:textSize="20sp" />

android:id="@+id/item_delete"

android:layout_width="wrap_content"

android:layout_height="match_parent"

android:background="#FF0000"

android:text="删除" />

如果需要复杂一点儿的item样式,那就把item_text换成自己想要的布局就好了~

然后看我们的重头戏,adapter

public class HorizontalSlideAdapter extends ArrayAdapter {

/** 屏幕宽度 */

private int mScreenWidth;

/** 删除按钮事件 */

private DeleteButtonOnclickImpl mDelOnclickImpl;

/** HorizontalScrollView左右滑动事件 */

private ScrollViewScrollImpl mScrollImpl;

/** 布局参数,动态让HorizontalScrollView中的TextView宽度包裹父容器 */

private LinearLayout.LayoutParams mParams;

/** 记录滑动出删除按钮的itemView */

public HorizontalScrollView mScrollView;

/** touch事件锁定,如果已经有滑动出删除按钮的itemView,就屏蔽下一整次(down,move,up)的onTouch操作 */

public boolean mLockOnTouch = false;

public HorizontalSlideAdapter(Context context, List objects) {

super(context, 0, objects);

// 搞到屏幕宽度

Display defaultDisplay = ((Activity) context).getWindowManager()

.getDefaultDisplay();

DisplayMetrics metrics = new DisplayMetrics();

defaultDisplay.getMetrics(metrics);

mScreenWidth = metrics.widthPixels;

mParams = new LinearLayout.LayoutParams(mScreenWidth,

LinearLayout.LayoutParams.MATCH_PARENT);

// 初始化删除按钮事件与item滑动事件

mDelOnclickImpl = new DeleteButtonOnclickImpl();

mScrollImpl = new ScrollViewScrollImpl();

}

@Override

public View getView(int position, View convertView, ViewGroup parent) {

ViewHolder holder = null;

if (convertView == null) {

holder = new ViewHolder();

convertView = View.inflate(getContext(),

R.layout.item_horizontal_slide_listview, null);

holder.scrollView = (HorizontalScrollView) convertView;

holder.scrollView.setOnTouchListener(mScrollImpl);

holder.infoTextView = (TextView) convertView

.findViewById(R.id.item_text);

// 设置item内容为fill_parent的

holder.infoTextView.setLayoutParams(mParams);

holder.deleteButton = (Button) convertView

.findViewById(R.id.item_delete);

holder.deleteButton.setOnClickListener(mDelOnclickImpl);

convertView.setTag(holder);

} else {

holder = (ViewHolder) convertView.getTag();

}

holder.position = position;

holder.deleteButton.setTag(holder);

holder.infoTextView.setText(getItem(position));

holder.scrollView.scrollTo(0, 0);

return convertView;

}

static class ViewHolder {

private HorizontalScrollView scrollView;

private TextView infoTextView;

private Button deleteButton;

private int position;

}

/** HorizontalScrollView的滑动事件 */

private class ScrollViewScrollImpl implements OnTouchListener {

/** 记录开始时的坐标 */

private float startX = 0;

@SuppressLint("ClickableViewAccessibility")

@Override

public boolean onTouch(View v, MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

// 如果有划出删除按钮的itemView,就让他滑回去并且锁定本次touch操作,解锁会在父组件的dispatchTouchEvent中进行

if (mScrollView != null) {

scrollView(mScrollView, HorizontalScrollView.FOCUS_LEFT);

mScrollView = null;

mLockOnTouch = true;

return true;

}

startX = event.getX();

break;

case MotionEvent.ACTION_UP:

HorizontalScrollView view = (HorizontalScrollView) v;

// 如果滑动了>50个像素,就显示出删除按钮

if (startX > event.getX() + 50) {

startX = 0;// 因为公用一个事件处理对象,防止错乱,还原startX值

scrollView(view, HorizontalScrollView.FOCUS_RIGHT);

mScrollView = view;

} else {

scrollView(view, HorizontalScrollView.FOCUS_LEFT);

}

break;

}

return false;

}

}

/** HorizontalScrollView左右滑动 */

public void scrollView(final HorizontalScrollView view, final int parameter) {

view.post(new Runnable() {

@Override

public void run() {

view.pageScroll(parameter);

}

});

}

/** 删除事件 */

private class DeleteButtonOnclickImpl implements OnClickListener {

@Override

public void onClick(View v) {

final ViewHolder holder = (ViewHolder) v.getTag();

Toast.makeText(getContext(), "删除第" + holder.position + "项",

Toast.LENGTH_SHORT).show();

Animation animation = AnimationUtils.loadAnimation(getContext(),

R.anim.anim_item_delete);

holder.scrollView.startAnimation(animation);

animation.setAnimationListener(new AnimationListener() {

@Override

public void onAnimationStart(Animation animation) {

}

@Override

public void onAnimationRepeat(Animation animation) {

}

@Override

public void onAnimationEnd(Animation animation) {

remove(getItem(holder.position));

}

});

}

}

}有点儿长,首先是获取当前屏幕宽度,态的给每一个ItemView让他填充父容器(因为宽度是屏幕宽度)。

再之后就是对onTouch事件的处理,这一点注释里面写的比较详细就不再赘述了。

看到这儿也许就会有点儿纳闷了,唉 既然吧事件锁上了,,怎么没见打开啊?

嗯,这也是我当时在编写这个侧滑时遇到的问题,我们不仅仅是只让删除按钮只出现一个就行了,我们还需要在出现删除按钮时也让ListView的滑动失效!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/555754.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java IO体系的学习总结

1.Java Io流的概念,分类,类图。 1.1 Java Io流的概念 ? ? java的io是实现输入和输出的基础,可以方便的实现数据的输入和输出操作。在java中把不同的输入/输出源(键盘,文件,网络连接等)抽象表…

android 浏览器 多窗口显示,Android浏览器图形侧多窗口方案

Android平台浏览器当前多窗口方案为多个浏览器子窗口公用一个图形buffer,窗口的z序和显示控制由浏览器进程维护,图形侧只能看到一个窗口。该方案能基本实现浏览器多窗口的大部分需求。但无法实现linux机顶盒中存在的部分窗口交叉的业务场景,即…

response.reset() 与response.resetbuffer使用场景

getResponse的getWriter()方法 getResponse的getWriter()方法连续两次输出流到页面的时候,第二次的流会包括第一次的流,所以可以使用response.reset或者resetBuffer的方法。 reset(): Clears any data that exists in the buffer as well as the statu…

android listview asynctask,关于android:ListView + ArrayList + AsyncTask

本问题已经有最佳答案,请猛点这里访问。我的想法是使用AsynTask下载数据集并存储在arrayList中。 我已经检查并运行良好。在onPostExecute方法中,我调用一个函数来更新listView,然后加载存储在ArrayList中的数据。码:protected vo…

ServletResponse reset()方法慎用

reset()用于重置,但是在重置的时候也会清空相关数据,例如session存的信息。

android10获取imei,Android 10 root用户获取imei

IMEI(International Mobile Equipment Identity)是国际移动设备识别码的缩写,由15-17位数字组成,与手机是一一对应的关系。无论刷机还是恢复出厂设置,该设备标识码都不会改变,所以在广告和流量统计等方面特别好用,备受…

JAVA基础之HttpServletResponse响应

JAVA基础之HttpServletResponse响应 用户在客户端输入网址(虚拟路径)时,开始发送一个HTTP请求(请求行、请求头、请求体)至服务器。服务器内的Tomcat引擎会解析请求的地址,去找XML文件,然后根据…

android imageview 设置网络图片,ImageView加载网络图片

android网络加载图片框架Android-Universal-Image-Loader功能非常强大,其开源地址https://github.com/nostra13/Android-Universal-Image-Loader,讲解非常地详细,今天我要贴下工作中用到的利用这个框架加载网络图片并在ImageView控件中显示出…

Logger之Logger.getLogger(CLass)

之前一直在使用System.out.println()来调试.但是用这种方式开发项目部署到生产环境,会因为众多的控制台输出降低应用的性能.这时候Log4J就成为可平衡开发和部署应用的利器了. 在项目中使用Log4J并不是一件困难的事情,简单粗暴的方式就是在每个类A中声明一个Logger私有属性 pri…

订阅号助手android,微信订阅号助手app

微信订阅号助手app属于微信官方推出的软件,可以把我们的手机当做公众号的平台,让你直接用手机来实现公众号的各种工作、互动内容,微信订阅号助手app不用担心使用一些第三方软件被封号了,非常实用可靠。【应用介绍】订阅号助手是一…

使用LoggerFactory.getLogger(xxx.class)方法在控制台打印日志信息

使用System.out.println()来调试.但是用这种方式开发项目部署到生产环境,会因为众多的控制台输出降低应用的性能.这时候Log4J就成为可平衡开发和部署应用的利器了. 使用指定的类XXX初始化日志对象,方便在日志输出的时候,可以打印出日志信息所属的类。 …

signature=f0dd2033ed5bb3cdb94f9136381f7750,Lesson 8: Signature Assignment

摘要:This unit will focus on the Civil Rights Era in the 1960s. Students will learn what the Civil Rights Movement was and how it changed the United States. By learning about the pivotal leaders of the movement, students will build their underst…

LoggerFactory.getLogger的用法

Logger类下有多个不同的error方法,根据传入参数的个数及类型的不同,自动选择不同的重载方法。 使用,只打印异常,不打印堆栈信息 private static final Logger logger LoggerFactory.getLogger(LoggerTest.class);Testpublic voi…

html自动增加vbs代码,vbs脚本病毒代码大全编步骤四个

应用程序通过ActiveX的属性HTMLPageTextWithTags(主页不嵌有HTML代码时用属性HTMLPageTextWithOutTags)读页面文本交互模式;允许显示用户提示和脚本错误2.ntlm.vbs***************ntlm.vbsby黑嘿黑***************dimwshsetwshCreateObject("WScript.Shell&quo…

java util logger slf4j_别再自己用LoggerFactory生成logger实例了,试试slf4j注解

背景 在项目开发中,记录日志是必做的一件事情。日志的实现有很多种:Logback,Log4j2,log4j,JAVA Util Logging等等。 而slf4j是一个适配层,由适配层决定使用哪一种日志系统,而调用端只需要做的…

正则匹配承兑的html,正则匹配闭合HTML标签(支持嵌套)

原标题:正则匹配闭合HTML标签(支持嵌套)任何复杂的正则表达式都是由简单的子表达式组成的,要想写出复杂的正则来,一方面需要有化繁为简的功底,另外一方面,我们需要从正则引擎的角度去思考问题。关于正则引擎的原理&…

private static Logger logger =Logger.getLogger(AssembleMsgService.class)什么意思?

作为一个新人中的菜鸡,最近在看一个项目的代码其中有这么一段看得我很是费解 public class AssembleMsgService {private static Logger logger Logger.getLogger(AssembleMsgService.class);1、Logger logger logger.getlogger(); 看到这个会想到这是log4j下的…

日志框架介绍(SLF4J及其使用)

本文主要介绍 1.日志框架基本介绍及Spring Boot中默认使用框架(SLF4JLogBack); 2.SLF4J的使用 3.项目中日志框架统一问题 4.Spring Boot中如何实现日志框架统一问题(3的最佳实践) 1. 日志框架基本介绍 一般情况下搭建日志框架时,搭建 日志抽象层(定…

jmeter生成html报告修改,Jmeter生成html报告(示例代码)

新的JMeter版本中引入了Dashboard Report,用于生成HTML页面格式图形化报告的扩展模块。注:本文用的是3.2版本。生成html报告一、检查.jtl文件,如果没有.jtl文件,运行如下命令:jmeter -n -t 天气api.jmx -l result.jtl …

SpringBoot使用Slf4j+Log4j2完成项目的日志记录

SpringBoot使用Slf4jLog4j完成项目的日志记录 前言 本示例采用SpringBoot项目使用SpringAOP记录日志,Slf4j作为日志门面,Log4j2作为日志实现实,实现开发中的日志记录. 部分效果展示 : 日志文件 : 日志信息 : 代码具体实现如下…