今天研究了一下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左右滑动事件`是一种常见的需求,特别是在社交应用或者带有交互式列表的场景中。本项目名为`SwipeListView`,它为ListView提供了滑动触发事件的功能,用户可以自定义左右滑动的位移和动画时间,从而...
通过以上步骤,我们就成功实现了自定义ListView,使其具有滑动显示删除按钮的功能。这只是一个基础实现,实际项目中可能还需要考虑性能优化,例如使用ViewHolder模式减少视图复用时的查找成本,以及添加触摸冲突处理...
总结来说,这个"android自定义listview滑动删除"案例涵盖了Android自定义组件、事件监听、布局设计和动画应用等多个方面,对于提升Android开发者的UI交互设计和性能优化能力非常有帮助。通过学习和实践这个案例,你...
为了提供更丰富的交互体验,开发者经常需要自定义ListView,实现如滑动删除Item等高级功能。本篇文章将详细讲解如何在Android中通过自定义控件来实现ListView的滑动删除功能。 首先,我们需要了解ListView的基本...
4. 动画效果:为了提供更好的用户体验,可以添加滑动删除动画和ViewPager翻页动画。 总的来说,实现这样的功能需要对Android的UI组件有深入的理解,以及对触摸事件处理、自定义Adapter和手势识别的熟悉。通过合理的...
综上所述,实现ListView的滑动删除功能涉及多个步骤,包括引入第三方库、创建菜单、自定义适配器、设置监听器、添加动画效果、性能优化以及安全处理。熟练掌握这些要点,能帮助开发者在Android应用中构建出高效且...
"Listview左右滑动删除item"是实现ListView的一项高级功能,它允许用户通过手势操作直接在列表中删除项目,增强了用户体验。这种功能常见于邮件应用、通讯录等需要频繁删除条目的场景。 实现这个功能通常涉及到以下...
在Android开发中,ListView是...在实际开发中,你可能还需要根据具体需求进行更多的定制,比如添加长按删除功能、添加滑动手势等。通过这样的自定义,我们可以使ListView更好地适应各种应用场景,提高用户的操作体验。
ListView的滑动删除功能使得用户可以方便地通过手势操作来移除列表中的条目,极大地提升了用户体验。本篇将详细介绍如何实现ListView的滑动删除item的功能,并提供相关的编程技巧。 一、基本原理 滑动删除的核心...
这些库提供了内置的滑动功能,可以轻松地添加滑动删除效果。例如,SwipeMenuListView允许我们为每个Item定义一个菜单,包括删除按钮,并提供了滑动触发菜单的接口。 在适配器(Adapter)中,我们需要实现逻辑来处理...
总结来说,实现ListView的滑动删除功能涉及到自定义Adapter、监听滑动事件、处理删除逻辑、提供视觉反馈以及可能的撤销机制。这个过程需要开发者具备扎实的Android基础,理解ListView的工作原理,以及熟悉第三方库的...
在Android开发中,ListView是一种常用的组件,用于展示可滚动的多行数据列表。...开发者可以通过阅读和学习这些代码,加深对Android自定义ListView和PopupWindow的理解,从而更好地实现自己的项目需求。
在这个项目中,我们关注的是如何将"滑动删除"和"下拉刷新加载更多"这两个功能整合到一个ListView中,提升用户体验。以下是对这两个功能的详细解释以及实现方法。 **滑动删除(Swipe to Delete)** 滑动删除是用户...
`SlideCut`这个文件名可能指的是一个实现滑动删除效果的自定义ListView项的示例代码或库。本篇文章将详细探讨如何在ListView中实现滑动删除Item的特效。 首先,要实现滑动删除效果,我们需要对ListView的每个Item...
这个自定义ListView库名为`DragSortListView`,它允许用户通过直观的拖放操作对列表项进行排序,同时支持左右滑动触发删除操作。这对于需要动态调整数据顺序或者需要快速删除列表项的应用场景非常有用。例如,在音乐...
标题"listview横向滑动item删除item"和描述"listview横向滑动删除item,完整demo"表明我们要讨论的是如何为ListView添加一个自定义的功能,即在水平滑动时删除列表项。这个功能可以提高用户的交互体验,让用户更加...
在Android开发中,ListView是一种常用的组件,用于展示大量的数据列表。本教程将深入探讨如何实现滑动删除功能以及CheckBox点击...通过这个教程,开发者可以掌握自定义ListView的高级用法,提升Android应用的用户体验。
本项目"Android 重写Listview实现左滑删除功能"旨在教你如何在ListView中添加滑动删除的交互效果。 首先,我们需要理解ListView的工作原理。ListView通过复用View(也称为ViewHolder模式)来优化性能,减少内存消耗...