今天研究了一下android里面的手势,结合昨天学习的自定义View,做了一个自定义的listview,继承自listView,添加了条目的滑动手势操作,滑动后出现一个删除按钮,点击删除按钮,触发一个删除的事件,在事件中进行删除当选行的元素,刷新listview。

一共分为以下几步进行:

1、新建一个按钮的布局文件,用来作为动态添加的按钮:layout_button.xml

<?xml version="1.0" encoding="utf-8"?>
<Button
xmlns:android="http://schemas.android.com/apk/res/android"
android:text="删除"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn1"/>

2、定义按钮显示,隐藏的动画效果,简单的缩放动画:

btn_hide.xml:

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="1.0"
android:toXScale="0"
android:fromYScale="1.0"
android:toYScale="1.0"
android:pivotX="100%"
android:pivotY="0"
android:duration="200"
/>

btn_show.xml:

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="0"
android:toXScale="1.0"
android:fromYScale="1.0"
android:toYScale="1.0"
android:pivotX="100%"
android:pivotY="0"
android:duration="200"
/>

3、自定义ListView,继承自listView,并实现OnTouchListener,OnGestureListener接口,代码就不一步一步写了,里面我尽可能的注释详细一些:MyListView.java

package com.example.viewtest;

import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.widget.ListView;
import android.widget.RelativeLayout;
/**
* 项目名称:viewTest
* 实现功能: 自定义ListView,增加滑动删除功能
* 类名称:MyListView
* 类描述:(该类的主要功能)
* 创建人:徐纪伟
* E-mail: xujiwei558@126.com
* 创建时间:2014年11月2日 下午3:37:40
* 修改人:
* 修改时间:
* 修改备注:
* @version
*/
public class MyListView extends ListView implements OnTouchListener,OnGestureListener { /**
* 手势识别类
*/
private GestureDetector gestureDetector; /**
* 滑动时出现的按钮
*/
private View btnDelete; /**
* listview的每一个item的布局
*/
private ViewGroup viewGroup;
/**
* 选中的项
*/
private int selectedItem; /**
* 是否已经显示删除按钮
*/
private boolean isDeleteShow; /**
* 点击删除按钮时删除每一行的事件监听器
*/
private OnItemDeleteListener onItemDeleteListener; /**
* 构造函数,初始化手势监听器等
* @param context
* @param attrs
*/
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
gestureDetector = new GestureDetector(getContext(),this);
setOnTouchListener(this);
} public void setOnItemDeleteListener(OnItemDeleteListener onItemDeleteListener) {
this.onItemDeleteListener = onItemDeleteListener;
} @Override
public boolean onTouch(View v, MotionEvent event) {
//得到当前触摸的条目
selectedItem = pointToPosition((int)event.getX(), (int)event.getY());
//如果删除按钮已经显示,那么隐藏按钮,异常按钮在当前位置的绘制
if (isDeleteShow) {
btnHide(btnDelete);
viewGroup.removeView(btnDelete);
btnDelete = null;
isDeleteShow = false;
return false;
}else{
//如果按钮没显示,则触发手势事件
//由此去触发GestureDetector的事件,可以查看其源码得知,onTouchEvent中进行了手势判断,调用onFling
return gestureDetector.onTouchEvent(event);
} } @Override
public boolean onDown(MotionEvent e) {
//得到当前触摸的条目
if (!isDeleteShow) {
selectedItem = pointToPosition((int)e.getX(), (int)e.getY());
}
return true;
} @Override
public void onShowPress(MotionEvent e) { } @Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
} @Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
return false;
} @Override
public void onLongPress(MotionEvent e) { } /**
* 滑动删除的主要响应方法。
*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
//如果删除按钮没有显示,并且手势滑动符合我们的条件
//此处可以根据需要进行手势滑动的判断,如限制左滑还是右滑,我这里是左滑右滑都可以
if (!isDeleteShow && Math.abs(velocityX) > Math.abs(velocityY)) {
//在当前布局上,动态添加我们的删除按钮,设置按钮的各种参数、事件,按钮的点击事件响应我们的删除项监听器
btnDelete = LayoutInflater.from(getContext()).inflate(R.layout.layout_button, null);
btnDelete.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
//btnHide(btnDelete);
viewGroup.removeView(btnDelete);
btnDelete = null;
isDeleteShow = false;
onItemDeleteListener.onItemDelete(selectedItem);
}
});
viewGroup = (ViewGroup)getChildAt(selectedItem - getFirstVisiblePosition());
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
layoutParams.addRule(RelativeLayout.CENTER_VERTICAL);
btnDelete.setLayoutParams(layoutParams);
viewGroup.addView(btnDelete);
btnShow(btnDelete);
isDeleteShow = true;
}else{
setOnTouchListener(this);
} return false;
} /**
* @类名称: OnItemDeleteListener
* @描述: 删除按钮监听器
* @throws
* @author 徐纪伟
* 2014年11月9日上午11:25:37
*/
public interface OnItemDeleteListener{
public void onItemDelete(int selectedItem);
} /**
* @方法名称: btnShow
* @描述: 按钮显示时的动画
* @param @param v
* @return void
* @throws
* @author 徐纪伟
* 2014年11月9日 上午11:25:12
*/
private void btnShow(View v){
v.startAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.btn_show));
}
/**
* @方法名称: btnHide
* @描述: 按钮隐藏时的动画
* @param @param v
* @return void
* @throws
* @author 徐纪伟
* 2014年11月9日 上午11:25:23
*/
private void btnHide(View v){
v.startAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.btn_hide));
} }

4、使用方法,布局文件,activity,很简单activity_main.xml:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" > <com.example.viewtest.MyListView
android:id="@+id/my_listview"
android:layout_width="match_parent"
android:layout_height="match_parent"> </com.example.viewtest.MyListView>
</RelativeLayout>

listview的每一个item的布局文件,一个textview,item.xml:

<?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="match_parent" > <TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text="TextView" /> </RelativeLayout>

activity,初始化listview,adapter的使用就不在介绍,跟普通的一样,唯一不同的就是,要给我们的自定义listview添加我们自定义的删除按钮单击事件,以此来响应我们的删除事件,MainActivity.java:

package com.example.viewtest;

import java.util.LinkedList;
import java.util.List; import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView; import com.example.viewtest.MyListView.OnItemDeleteListener; public class MainActivity extends ActionBarActivity { /**
* 自定义listview对象
*/
private MyListView myListview;
/**
* listView的数据集合
*/
private List<String> contentList = new LinkedList<String>();
/**
* 自定义数据适配器
*/
private MyAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化数据
setData();
myListview = (MyListView)findViewById(R.id.my_listview);
adapter = new MyAdapter(this);
myListview.setAdapter(adapter);
//添加自定义listview的按钮单击事件,处理删除结果,和普通listview使用的唯一不同之处,
myListview.setOnItemDeleteListener(new OnItemDeleteListener() {
@Override
public void onItemDelete(int index) {
contentList.remove(index);
adapter.notifyDataSetChanged();
}
});
} @Override
public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
} /**
* @类名称: MyAdapter
* @描述: 自定义数据适配器
* @throws
* @author 徐纪伟
* 2014年11月9日下午12:20:19
*/
class MyAdapter extends BaseAdapter{ private Context context;
public MyAdapter(Context context) {
this.context = context;
} @Override
public int getCount() {
// TODO Auto-generated method stub
return contentList.size();
} @Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return contentList.get(position);
} @Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.item, null);
}
TextView textView = (TextView)convertView.findViewById(R.id.textView1);
textView.setText(contentList.get(position));
return convertView;
}
} /**
* @方法名称: setData
* @描述: 初始化数据
* @param
* @return void
* @throws
* @author 徐纪伟
* 2014年11月9日 下午12:20:32
*/
private void setData() { for (int i = 0; i < 30; i++) {
contentList.add("Item "+i);
}
} }

运行效果:

再给button加上selector背景,更好看一些:selector_btn_red.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:drawable="@drawable/btn_style_zero_pressed"></item>
<item android:state_pressed="false" android:drawable="@drawable/btn_style_zero_normal"></item> </selector>

资源图片在附件源码中上传。

最终效果:

图片显示的位置在自定义listview中可以调整。

自定义listView添加滑动删除功能的更多相关文章

  1. android 继承ListView实现滑动删除功能.

    在一些用户体验较好的应用上,可以经常遇见   在ListView中  向左或向右滑动便可删除那一项列表. 具体实现  则是继承ListView实现特定功能即可. (1). 新建 delete_butt ...

  2. Android 使用NineOldAndroids实现绚丽的ListView左右滑动删除Item效果

    本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/18311877) 今天还是给大家带来自定义控件的编写,自定义一个Lis ...

  3. 【转】Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果

    原文网址:http://blog.csdn.net/xiaanming/article/details/17539199 转帖请注明本文出自xiaanming的博客(http://blog.csdn. ...

  4. [转]Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果

    转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17539199),请尊重他人的辛勤劳动成果,谢谢! 我在上一 ...

  5. Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果

    转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17539199),请尊重他人的辛勤劳动成果,谢谢! 我在上一 ...

  6. 使用vue实现用户管理 添加及删除功能

    简单的管理系统-增删改查 添加及删除功能 <!DOCTYPE html> <html> <head> <meta charset="UTF-8&qu ...

  7. [vs2008]Visual Studio 2008 SP1添加或删除功能提示查找SQLSysClrTypes.msi文件

    前言 今天接到领导布置的一个任务,是之前同事负责的项目.离职了,现在客户有些地方需要修改,由于我之前参与过,就落在我的头上了. 然后我就把代码弄了过来,打开发现其中需要用到水晶报表.(我觉得不好用,不 ...

  8. 【转】Android 实现ListView的滑动删除效果

    http://www.cnblogs.com/weixiao870428/p/3524055.html http://download.csdn.net/download/love_javc_you/ ...

  9. 使用Style自定义ListView快速滑动图标

    一.显示ListView快速滑动块图标 设想这样一个场景,当ListView的内容有大于100页的情况下,如果想滑动到第80页,用手指滑动到指定位置,无疑是一件很费时的事情,如果想快速滑动到指定的位置 ...

随机推荐

  1. Java数据库连接之配置ODBC数据源

    java使用JDBC-ODBC桥接连接SQLServer数据库需要配置ODBC数据源,配置步骤如下: 1.进入控制面板,找到管理工具 2.看到ODBC数据源,有64位和32位的,如果你的数据库是64位 ...

  2. LINQ Enumerable

    System.Linq.Enumerable类,提供了数十种称为扩展方法的共享方法,帮助您操作所有实现IEnumerable(of T)接口的类中的数据.由于Enumerable类的扩展方法可以处理许 ...

  3. (转)精通 JS正则表达式

    精通 JS正则表达式 (精通?标题党 ) 正则表达式可以: •测试字符串的某个模式.例如,可以对一个输入字符串进行测试,看在该字符串是否存在一个电话号码模式或一个信用卡号码模式.这称为数据有效性验证  ...

  4. SQL 查询字段为值不为空

      方法一sql="select   *   from   table   where   id<>null   "     or   sql="select ...

  5. 《Linux内核分析》 week6作业-Linux内核fork()系统调用的创建过程

    一.进程控制块PCB-stack_struct 进程在操作系统中都有一个结构,用于表示这个进程.这就是进程控制块(PCB),在Linux中具体实现是task_struct数据结构,它主要记录了以下信息 ...

  6. 获取元素位置信息:getBoundingClientRect

    一个神奇的方法. 一.历史 偷个懒,上个传送门:http://www.cnblogs.com/2050/archive/2012/02/01/2335211.html 二.介绍 DOM元素方法,返回一 ...

  7. Web开发-各状态码的意思

    常见的HTTP 1.1状态码以及它们对应的状态信息和含义 100 Continue 初始的请求已经接受,客户应当继续发送请求的其余部分.(HTTP 1.1新) 101 Switching Protoc ...

  8. win7禁止自动使用浏览器打开FTP而是用资源管理器

    Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\ftp] @="URL:File Transfer Protocol" ...

  9. JAVA多态示例

    这多态,我觉得是最利害的.在开发大型程序中. 但,也是需要经过足够多的实践经验才能随心利用的. class Quadrangle{ private Quadrangle[] qtest = new Q ...

  10. Special Pythagorean triplet

    这个比较简单,慢慢进入状态. A Pythagorean triplet is a set of three natural numbers, a b c, for which, a2 + b2 = ...