`
men4661273
  • 浏览: 275307 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

自定义listView添加滑动删除功能

 
阅读更多

        今天研究了一下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中可以调整。

   

  • 大小: 13.4 KB
  • 大小: 13.2 KB
2
0
分享到:
评论

相关推荐

    ListView侧滑删除+下拉刷新

    尝试在SwipeListView的顶部添加布局,实现一个自定义的可以下拉刷新的SwipeListView。 至于SwipeListView可以Github中下载项目库源代码。 其中需要用到NineOldAndroids_library,已包含提供的Demo中。

    安卓源码包android web应用OCR图像识别listview相关EditText输入框Launcher 桌面45个合集

    [四次元]仿QQ消息列表(ListView)滑动删除效果源码.rar [四次元]仿QQ的头像选择弹出的对话框,酷似!.zip [四次元]前面部分可以编辑后面部分不可编辑的EditText.zip [四次元]动态添加RadioGroup的RadioButton.zip [四...

    Android ListView实现上拉加载下拉刷新和滑动删除功能

    最近项目需要用到可以滑动删除并且带有上拉加载下拉刷新的Listview,查阅了一些资料,大多都是在SwipeMenuListView的基础上去添加头部和底部View,来扩展上拉加载和下拉刷新的功能,不过需要手动的去绘制UI及处理一些...

    虚拟来电源代码

    可以增加、删除来电,添加桌面快捷方式,代码分层架构。采用 Tabhost 自定义ListView 滑动显示删除按钮技术,耗时两周的成果,绝对值得借鉴。

    BRecyclerView:BRecyclerView(或“更好”的RecyclerView)是一种尝试,通过添加ListView的功能使RecyclerView更方便

    它具有以下功能: 触控效果: 支持的api的波纹效果,否则为普通的触摸效果自定义背景可绘制选择动作时自定义可绘制多选和操作 滑动即可删除添加分频器: 高度颜色PS:因为这是我的第一个库,所以我不能保证它会提供...

    强大的RecyclerAdapter框架

    添加拖拽、滑动删除 开启,监听即可,就是这么简单。 树形列表 比ExpandableListView还要强大,支持多级。 自定义ViewHolder 支持自定义ViewHolder,让开发者随心所欲。 扩展框架 组合第三方框架,轻松实现更多需求...

    黑马程序员 安卓学院 万元哥项目经理 分享220个代码实例

    |--ListView之动态添加子view |--ListView优化之分页加载 |--ListView优化之动态加载 |--ListView优化之控制getView实现复杂显示 |--ListView优化之标准写法 |--listview老虎机 界面设计 水果机 |--listview页面...

    Android开发艺术探索.任玉刚(带详细书签).pdf

    本书是一本Android进阶类书籍,采用理论、源码和实践相结合的... 15.1.5 ListView和Bitmap优化 501 15.1.6 线程优化 501 15.1.7 一些性能优化建议 501 15.2 内存泄露分析之MAT工具 502 15.3 提高程序的可维护性 506

    超实用的jQuery代码段

    10.18 为列表添加自定义的缩略图图标 10.19 创建列表日历的效果 10.20 动态创建listview列表项 10.21 动态加载和切换页面 10.22 在页面切换时显示加载进度框 10.23 在屏幕旋转时更改显示样式 10.24 在列表框中实现...

    Android开发艺术探索

    《Android开发艺术探索》是一本Android进阶类... 15.1.5 ListView和Bitmap优化 / 501  15.1.6 线程优化 / 501  15.1.7 一些性能优化建议 / 501  15.2 内存泄露分析之MAT工具 / 502  15.3 提高程序的可维护性 / 506

    Android开发资料合集--续

    2、递归删除目录或文件 57 30、手动更新所有Widget 58 31、有关ListView 问题 58 32、在手机上打开文件的方法 59 33、使用系统自带的TabHost的问题 59 34、弹出菜单 61 35、Toast重叠显示时延迟解决 62 36、ADT新...

    vc++ 应用源码包_1

    演示了不同的数据库的各种操作(连接、删除、添加……等等) ATL开发指南源码 内部包含了atl控件的开发以及如何应用,演示了COM的包容与集合、自动化、事件和连接点、枚举器和集合以及线程管理等等。 ATL实现的...

    vc++ 应用源码包_2

    演示了不同的数据库的各种操作(连接、删除、添加……等等) ATL开发指南源码 内部包含了atl控件的开发以及如何应用,演示了COM的包容与集合、自动化、事件和连接点、枚举器和集合以及线程管理等等。 ATL实现的...

    vc++ 应用源码包_6

    演示了不同的数据库的各种操作(连接、删除、添加……等等) ATL开发指南源码 内部包含了atl控件的开发以及如何应用,演示了COM的包容与集合、自动化、事件和连接点、枚举器和集合以及线程管理等等。 ATL实现的...

    vc++ 应用源码包_5

    演示了不同的数据库的各种操作(连接、删除、添加……等等) ATL开发指南源码 内部包含了atl控件的开发以及如何应用,演示了COM的包容与集合、自动化、事件和连接点、枚举器和集合以及线程管理等等。 ATL实现的...

    vc++ 应用源码包_3

    演示了不同的数据库的各种操作(连接、删除、添加……等等) ATL开发指南源码 内部包含了atl控件的开发以及如何应用,演示了COM的包容与集合、自动化、事件和连接点、枚举器和集合以及线程管理等等。 ATL实现的...

    《程序天下:JavaScript实例自学手册》光盘源码

    6.15 经典的ListView列表框 第7章 键盘操作和状态栏特效 7.1 按功能键返回首页 7.2 回车实现Tab键功能 7.3 Ctrl+Enter提交数据 7.4 IE中屏蔽退格建(Back Space) 7.5 屏蔽键盘所有键 7.6 JavaScript捕获方向键 7.7 ...

Global site tag (gtag.js) - Google Analytics