【android自定义控件】android ListView添加侧滑删除
来源:互联网 发布:windows caffe mnist 编辑:程序博客网 时间:2024/05/17 23:38
为ListView添加炫酷的Item中带侧滑的删除,原理是利用item布局中的padding(Left和Right)属性为负值,来把删除的按钮隐藏在屏幕外。然后通过自定义ListView重写其中的OnTouchEvent通过手指坐标点的计算来处理事件,实现itemView的滚动,达到滑动出现删除菜单,本例中仅实现右向左滑出现删除按钮,大家可以根据自己需求,参照自定义ListView中事件处理做出左侧滑,右侧滑出现菜单,当然不仅仅局限于删除。更多灵活用法期待发觉。
首先上自定义的ListSlideView代码,其中有有详细注释,我就不废话了!(该ListView参考以前项目里面的事件分发处理判断,具体参考了哪位大神的写法已无法考究,感谢最原先的作者的同时也请见谅,如见可联系博主,把参考出处加上)
ListSlideView:
/** * ListSlideView.java * 2015 下午3:00:24 */package com.example.slideviewtest;import android.content.Context;import android.content.res.TypedArray;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.ViewConfiguration;import android.widget.AdapterView;import android.widget.ListView;import android.widget.Scroller;/** * @note 自定义的listView,集成自系统的ListView,对list的OnTouchEnvent事件分发进行了拦截处理(最关键的地方, * 也是通过该方式实现了控制屏幕外布局的拖拽) 需要配合Item的布局文件来实现 * @author blank * @time 下午3:00:24 * @version V1.0 */public class ListSlideView extends ListView {/** 禁止侧滑模式 */public static int MODE_FORBID = 0;/** 从右向左滑出菜单模式 */public static int MODE_RIGHT = 1;/** 当前的模式 */private int mode = MODE_FORBID;/** 右侧菜单的长度 */private int rightLength = 0;/** * 当前滑动的ListView position */private int slidePosition;/** * 手指按下X的坐标 */private int downY;/** * 手指按下Y的坐标 */private int downX;/** * ListView的item */private View itemView;/** * 滑动类 */private Scroller scroller;/** * 认为是用户滑动的最小距离 */private int mTouchSlop;/** * 判断是否可以侧向滑动 */private boolean canMove = false;/** * 标示是否完成侧滑 */private boolean isSlided = false;public ListSlideView(Context context) {this(context, null);}public ListSlideView(Context context, AttributeSet attrs) {this(context, attrs, 0);TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.SlideMode);mode = a.getInt(R.styleable.SlideMode_mode, 0);}public ListSlideView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.SlideMode);mode = a.getInt(R.styleable.SlideMode_mode, 0);scroller = new Scroller(context);mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();}/** * 处理我们拖动ListView item的逻辑 */@Overridepublic boolean onTouchEvent(MotionEvent ev) {final int action = ev.getAction();int lastX = (int) ev.getX();switch (action) {case MotionEvent.ACTION_DOWN:System.out.println("touch-->" + "down");/* 默认不处理当前View的事件,即没有侧滑菜单 */if (this.mode == MODE_FORBID) {return super.onTouchEvent(ev);}// 侧滑状态判断if (isSlided) {scrollBack();return false;}// 滚动是否结束if (!scroller.isFinished()) {return false;}downX = (int) ev.getX();downY = (int) ev.getY();slidePosition = pointToPosition(downX, downY);// 无效的positionif (slidePosition == AdapterView.INVALID_POSITION) {return super.onTouchEvent(ev);}itemView = getChildAt(slidePosition - getFirstVisiblePosition());/* 右侧菜单的长度 */if (this.mode == MODE_RIGHT) {this.rightLength = -itemView.getPaddingRight();}break;case MotionEvent.ACTION_MOVE:System.out.println("touch-->" + "move");if (!canMove&& slidePosition != AdapterView.INVALID_POSITION&& (Math.abs(ev.getX() - downX) > mTouchSlop && Math.abs(ev.getY() - downY) < mTouchSlop)) {int offsetX = downX - lastX;if (offsetX > 0 && this.mode == MODE_RIGHT) {/* 从右向左滑 */canMove = true;} else {canMove = false;}/* 侧滑时ListView的OnItemClickListener事件的屏蔽 */MotionEvent cancelEvent = MotionEvent.obtain(ev);cancelEvent.setAction(MotionEvent.ACTION_CANCEL| (ev.getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT));onTouchEvent(cancelEvent);}if (canMove) {/* 侧滑动时,ListView不上下滚动 */requestDisallowInterceptTouchEvent(true);// 根据X坐标的差可以得到手指滑动方向,本例子可以根据自己的需要去灵活修改(左边划出菜单,右边划出菜单,或者左右均可)int deltaX = downX - lastX;if (deltaX > 0 && this.mode == MODE_RIGHT) {/* X坐标差大于0手指向右滑动 */itemView.scrollTo(deltaX, 0);} else {itemView.scrollTo(0, 0);}return true;}case MotionEvent.ACTION_UP:System.out.println("touch-->" + "up");if (canMove) {canMove = false;scrollByDistanceX();}break;}return super.onTouchEvent(ev);}/** * 根据手指滚动itemView的距离来判断是滚动到开始位置还是向左或者向右滚动 */private void scrollByDistanceX() {/* 当前模式不允许滑动,则直接返回 */if (this.mode == MODE_FORBID) {return;}if (itemView.getScrollX() > 0 && this.mode == MODE_RIGHT) {/* 从右向左滑 */if (itemView.getScrollX() >= rightLength / 2) {scrollLeft();} else {// 滚回原始位置scrollBack();}} else {// 滚回原始位置scrollBack();}}/** * 向左滑动 */private void scrollLeft() {isSlided = true;final int delta = (rightLength - itemView.getScrollX());// 调用startScroll方法来设置一些滚动的参数,我们在computeScroll()方法中调用scrollTo来滚动itemscroller.startScroll(itemView.getScrollX(), 0, delta, 0,Math.abs(delta));postInvalidate(); // 刷新itemView}/** * 侧滑菜单复原 */private void scrollBack() {isSlided = false;scroller.startScroll(itemView.getScrollX(), 0, -itemView.getScrollX(),0, Math.abs(itemView.getScrollX()));postInvalidate(); // 刷新itemView}@Overridepublic void computeScroll() {// 调用startScroll的时候scroller.computeScrollOffset()返回true,if (scroller.computeScrollOffset()) {// 让ListView item根据当前的滚动偏移量进行滚动itemView.scrollTo(scroller.getCurrX(), scroller.getCurrY());postInvalidate();}}/** * 复原 */public void slideBack() {this.scrollBack();}}
为了兼容以前的ListView添加了是否需要侧滑的自定义控件属性
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="SlideMode"> <attr name="mode"> <enum name="forbid" value="0"></enum> <enum name="right" value="1"></enum> </attr> </declare-styleable></resources>
0代表不支持侧滑,1代表支持右侧滑,可以根据自己需要去加上左侧滑
ItemView的布局:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/white" android:gravity="center_vertical" android:orientation="horizontal" android:paddingBottom="10dp" android:paddingRight="-90dp" android:paddingTop="10dp" android:weightSum="1" > <LinearLayout android:layout_width="0dp" android:layout_height="96dp" android:layout_weight="0.35" android:orientation="vertical" > <ImageView android:id="@+id/imgIcon" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" android:scaleType="fitXY" android:src="@drawable/images" /> <TextView android:id="@+id/tvPrice" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:text="$128.5" /> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="96dp" android:layout_weight="0.65" android:orientation="vertical" android:padding="5dp" > <TextView android:id="@+id/tvName" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" android:text="HP 14-P010NR 14 TOUCHSCREEN SLATEBOOK, NIVIDIA TE" android:textStyle="bold" /> <RatingBar android:id="@+id/ratingBar" style="?android:attr/ratingBarStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:numStars="5" /> </LinearLayout> <TextView android:id="@+id/tvDelete" android:layout_width="90dp" android:layout_height="96dp" android:layout_centerInParent="true" android:layout_marginRight="-5dp" android:background="@android:color/holo_red_light" android:gravity="center" android:text="Delete" android:textColor="@android:color/white" android:textSize="15sp" /></LinearLayout>
为了适配ListSlideView的适配器:
package com.example.slideviewtest;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;/** * @author blank * @time 下午4:01:07 * @version V1.0 */public class SlideViewAdapter extends BaseAdapter {private Context mContext;private LayoutInflater layoutInflr;private int itemtype = 1;private OnRemoveListener mRemoveListener;public int getItemtype() {return itemtype;}public void setItemtype(int itemtype) {this.itemtype = itemtype;}public SlideViewAdapter( Context context) {this.mContext = context;this.layoutInflr = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);}public void setRemoveListener(OnRemoveListener removeListener) {this.mRemoveListener = removeListener;}class Viewlayout {private TextView mDelete;// 隐藏的侧滑删除按钮}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn 10;}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn null;}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic View getView(final int position, View convertView, ViewGroup parent) {Viewlayout icom_view;if (convertView == null) {icom_view = new Viewlayout();convertView = layoutInflr.inflate(R.layout.item_product_listview,null);icom_view.mDelete = (TextView) convertView.findViewById(R.id.tvDelete);convertView.setTag(icom_view);} else {icom_view = (Viewlayout) convertView.getTag();}icom_view.mDelete.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubif(mRemoveListener!=null){mRemoveListener.onRemoveItem(position);}}});return convertView;}public interface OnRemoveListener {void onRemoveItem(int position);}}
demo没有做数据填充,把删除的事件回调出去了!
来2张效果图:
源码地址已修改为正确地址
源码下载地址:源码下载
1 0
- 【android自定义控件】android ListView添加侧滑删除
- Android 自定义listview,添加删除。
- Android 自定义ListView Item侧滑删除
- Android 自定义ListView控件
- Android开发--自定义控件实现listview的滑动删除item
- android自定义添加控件
- android listview焦点争端补充(侧滑添加和删除)
- android自定义listview滑动删除
- Android 自定义控件:高仿微信、QQ侧滑删除、分享效果
- Android Widget添加自定义控件
- android自定义控件---添加表情
- Android自定义控件添加属性
- 自定义SwipeLayout控件实现ListView条目侧滑出现删除按钮,点击实现删除ListView条目
- Android listview动态添加删除测试
- Android中ListView动态添加删除项
- Android中ListView动态添加删除项
- Android中ListView动态添加删除项
- Android中ListView动态添加删除项
- C++的静态成员函数指针
- 南邮 OJ 1100 最长回文子串
- 触摸事件分发机制总结
- The hierarchy of the type MethodBeforeAdvice is inconsistent
- [网络流24题] 05 圆桌聚餐(最大流判满流)
- 【android自定义控件】android ListView添加侧滑删除
- iOS学习笔记8-iOS 实现发送邮件和短信
- Java中String、StringBuffer和StringBuilder详解
- php redis
- 橡皮擦(转)
- CentOS yum源默认安装路径
- LD_LIBRARY_PATH
- Android的ListView的每一个Item都有不同的布局
- 20150804-反射及注解