效果:

静态导入

平滑移动到指定位置的模板代码

布局:

activity_main

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.sg31.sgslidecell.MainActivity" ><ListView android:layout_width="match_parent"android:layout_height="match_parent"android:id="@+id/lv"></ListView></RelativeLayout>

item_list

<?xml version="1.0" encoding="utf-8"?>
<com.sg31.sgslidecell.SGSlideCellLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/sl"android:layout_width="match_parent"android:layout_height="60dp"android:minHeight="60dp"android:background="#fff" ><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="match_parent"android:orientation="horizontal" ><TextViewandroid:id="@+id/tv_call"android:layout_width="60dp"android:layout_height="match_parent"android:background="#666666"android:gravity="center"android:text="Call"android:textColor="#ffffff" /><TextViewandroid:id="@+id/tv_del"android:layout_width="60dp"android:layout_height="match_parent"android:background="#ff0000"android:gravity="center"android:text="Delete"android:textColor="#ffffff" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:background="#44ffffff"android:gravity="center_vertical"android:orientation="horizontal" ><ImageViewandroid:id="@+id/iv_image"android:layout_width="40dp"android:layout_height="40dp"android:layout_marginLeft="15dp"android:src="@drawable/head_1" /><TextViewandroid:id="@+id/tv_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="15dp"android:text="beyond" /></LinearLayout></com.sg31.sgslidecell.SGSlideCellLayout>

主控制器

package com.sg31.sgslidecell;import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;public class MainActivity extends ActionBarActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ListView mList = (ListView) findViewById(R.id.lv);mList.setAdapter(new SGAdapter(MainActivity.this));}
}

工具类

package com.sg31.sgslidecell;import android.content.Context;
import android.graphics.Rect;
import android.support.v4.view.MotionEventCompat;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;public class Utils {public static Toast mToast;public static void showToast(Context mContext, String msg) {if (mToast == null) {mToast = Toast.makeText(mContext, "", Toast.LENGTH_SHORT);}mToast.setText(msg);mToast.show();}/*** dip 转换成 px* * @param dip* @param context* @return*/public static float dip2Dimension(float dip, Context context) {DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip,displayMetrics);}/*** @param dip* @param context* @param complexUnit*            {@link TypedValue#COMPLEX_UNIT_DIP}*            {@link TypedValue#COMPLEX_UNIT_SP}* @return*/public static float toDimension(float dip, Context context, int complexUnit) {DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();return TypedValue.applyDimension(complexUnit, dip, displayMetrics);}/*** 获取状态栏高度* * @param v* @return*/public static int getStatusBarHeight(View v) {if (v == null) {return 0;}Rect frame = new Rect();v.getWindowVisibleDisplayFrame(frame);return frame.top;}public static String getActionName(MotionEvent event) {String action = "unknow";switch (MotionEventCompat.getActionMasked(event)) {case MotionEvent.ACTION_DOWN:action = "ACTION_DOWN";break;case MotionEvent.ACTION_MOVE:action = "ACTION_MOVE";break;case MotionEvent.ACTION_UP:action = "ACTION_UP";break;case MotionEvent.ACTION_CANCEL:action = "ACTION_CANCEL";break;case MotionEvent.ACTION_SCROLL:action = "ACTION_SCROLL";break;case MotionEvent.ACTION_OUTSIDE:action = "ACTION_SCROLL";break;default:break;}return action;}
}
package com.sg31.sgslidecell;
public class Cheeses {public static final String[] NAMES = new String[] { "宋江", "卢俊义", "吴用","公孙胜", "关胜", "林冲", "秦明", "呼延灼", "花荣", "柴进", "李应", "朱仝", "鲁智深","武松", "董平", "张清", "杨志", "徐宁", "索超", "戴宗", "刘唐", "李逵", "史进", "穆弘","雷横", "李俊", "阮小二", "张横", "阮小五", " 张顺", "阮小七", "杨雄", "石秀", "解珍"," 解宝", "燕青", "朱武", "黄信", "孙立", "宣赞", "郝思文", "韩滔", "彭玘", "单廷珪","魏定国", "萧让", "裴宣", "欧鹏", "邓飞", " 燕顺", "杨林", "凌振", "蒋敬", "吕方","郭 盛", "安道全", "皇甫端", "王英", "扈三娘", "鲍旭", "樊瑞", "孔明", "孔亮", "项充","李衮", "金大坚", "马麟", "童威", "童猛", "孟康", "侯健", "陈达", "杨春", "郑天寿","陶宗旺", "宋清", "乐和", "龚旺", "丁得孙", "穆春", "曹正", "宋万", "杜迁", "薛永", "施恩","周通", "李忠", "杜兴", "汤隆", "邹渊", "邹润", "朱富", "朱贵", "蔡福", "蔡庆", "李立","李云", "焦挺", "石勇", "孙新", "顾大嫂", "张青", "孙二娘", " 王定六", "郁保四", "白胜","时迁", "段景柱" };}

适配器

package com.sg31.sgslidecell;import static com.sg31.sgslidecell.Cheeses.NAMES;
import java.util.ArrayList;import com.sg31.sgslidecell.SGSlideCellLayout.OnSlideCellLayoutStateChangeListener;import android.content.Context;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;public class SGAdapter extends BaseAdapter {protected static final String TAG = "TAG";public SGAdapter(Context context) {super();this.context = context;opendItems = new ArrayList<SGSlideCellLayout>();}private Context context;private ArrayList<SGSlideCellLayout> opendItems;@Overridepublic int getCount() {return NAMES.length;}@Overridepublic Object getItem(int position) {return NAMES[position];}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {View view = convertView;if(convertView == null){view = View.inflate(context, R.layout.item_list, null);}ViewHolder mHolder = ViewHolder.getHolder(view);mHolder.tv_name.setText(NAMES[position]);SGSlideCellLayout sl = (SGSlideCellLayout)view;sl.setSwipeLayoutListener(new OnSlideCellLayoutStateChangeListener() {@Overridepublic void onStartOpen(SGSlideCellLayout mSwipeLayout) {Log.d(TAG, "onStartOpen");// 要去开启时,先遍历所有已打开条目, 逐个关闭for (SGSlideCellLayout layout : opendItems) {layout.close();}opendItems.clear();}@Overridepublic void onStartClose(SGSlideCellLayout mSwipeLayout) {Log.d(TAG, "onStartClose");}@Overridepublic void onOpen(SGSlideCellLayout mSwipeLayout) {Log.d(TAG, "onOpen");// 添加进集合opendItems.add(mSwipeLayout);}@Overridepublic void onDraging(SGSlideCellLayout mSwipeLayout) {}@Overridepublic void onClose(SGSlideCellLayout mSwipeLayout) {Log.d(TAG, "onClose");// 移除集合opendItems.remove(mSwipeLayout);}});return view;}static class ViewHolder {TextView tv_name;TextView tv_call;TextView tv_del;public static ViewHolder getHolder(View view) {Object tag = view.getTag();if(tag == null){ViewHolder viewHolder = new ViewHolder();viewHolder.tv_name = (TextView)view.findViewById(R.id.tv_name);viewHolder.tv_call = (TextView)view.findViewById(R.id.tv_call);viewHolder.tv_del = (TextView)view.findViewById(R.id.tv_del);tag = viewHolder;view.setTag(tag);}return (ViewHolder)tag;}}}

自定义Layout

package com.sg31.sgslidecell;import android.content.Context;
import android.graphics.Rect;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;/*** 侧拉删除控件* @author poplar**/
public class SGSlideCellLayout extends FrameLayout {private Status status = Status.Close;private OnSlideCellLayoutStateChangeListener swipeLayoutListener;public Status getStatus() {return status;}public void setStatus(Status status) {this.status = status;}public OnSlideCellLayoutStateChangeListener getSwipeLayoutListener() {return swipeLayoutListener;}public void setSwipeLayoutListener(OnSlideCellLayoutStateChangeListener swipeLayoutListener) {this.swipeLayoutListener = swipeLayoutListener;}public static enum Status{Close, Open, Draging}public static interface OnSlideCellLayoutStateChangeListener {void onClose(SGSlideCellLayout mSwipeLayout);void onOpen(SGSlideCellLayout mSwipeLayout);void onDraging(SGSlideCellLayout mSwipeLayout);// 要去关闭void onStartClose(SGSlideCellLayout mSwipeLayout);// 要去开启void onStartOpen(SGSlideCellLayout mSwipeLayout);}public SGSlideCellLayout(Context context) {this(context, null);}public SGSlideCellLayout(Context context, AttributeSet attrs) {this(context, attrs, 0);}public SGSlideCellLayout(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);mDragHelper = ViewDragHelper.create(this, 1.0f, mCallback);}ViewDragHelper.Callback mCallback = new ViewDragHelper.Callback() {// c. 重写监听public boolean tryCaptureView(View view, int id) {return true;}// 限定移动范围public int clampViewPositionHorizontal(View child, int left, int dx) {// leftif(child == mFrontView){if(left > 0){return 0;}else if(left < -mRange){return -mRange;}}else if (child == mBackView) {if(left > mWidth){return mWidth;}else if (left < mWidth - mRange) {return mWidth - mRange;}}return left;};public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {// 传递事件if(changedView == mFrontView){mBackView.offsetLeftAndRight(dx);}else if (changedView == mBackView) {mFrontView.offsetLeftAndRight(dx);}dispatchSwipeEvent();// 兼容老版本invalidate();};public void onViewReleased(View releasedChild, float xvel, float yvel) {if (xvel == 0 && mFrontView.getLeft() < -mRange / 2.0f) {open();}else if (xvel < 0) {open();}else {close();}};};private ViewDragHelper mDragHelper;private View mBackView;private View mFrontView;private int mHeight;private int mWidth;private int mRange;// b. 传递触摸事件@Overridepublic boolean onInterceptTouchEvent(android.view.MotionEvent ev) {return mDragHelper.shouldInterceptTouchEvent(ev);};protected void dispatchSwipeEvent() {if(swipeLayoutListener != null){swipeLayoutListener.onDraging(this);}// 记录上一次的状态Status preStatus = status;// 更新当前状态status = updateStatus();if (preStatus != status && swipeLayoutListener != null) {if (status == Status.Close) {swipeLayoutListener.onClose(this);} else if (status == Status.Open) {swipeLayoutListener.onOpen(this);} else if (status == Status.Draging) {if(preStatus == Status.Close){swipeLayoutListener.onStartOpen(this);}else if (preStatus == Status.Open) {swipeLayoutListener.onStartClose(this);}}}}private Status updateStatus() {int left = mFrontView.getLeft();if(left == 0){return Status.Close;}else if (left == -mRange) {return Status.Open;}return Status.Draging;}public void close() {Utils.showToast(getContext(), "Close");close(true);}public void close(boolean isSmooth){int finalLeft = 0;if(isSmooth){//开始动画if(mDragHelper.smoothSlideViewTo(mFrontView, finalLeft, 0)){ViewCompat.postInvalidateOnAnimation(this);}}else {layoutContent(false);}}public void open() {Utils.showToast(getContext(), "Open");open(true);}public void open(boolean isSmooth){int finalLeft = -mRange;if(isSmooth){//开始动画if(mDragHelper.smoothSlideViewTo(mFrontView, finalLeft, 0)){ViewCompat.postInvalidateOnAnimation(this);}}else {layoutContent(true);}}public void computeScroll() {super.computeScroll();if(mDragHelper.continueSettling(true)){ViewCompat.postInvalidateOnAnimation(this);}}public boolean onTouchEvent(MotionEvent event) {try {mDragHelper.processTouchEvent(event);} catch (Exception e) {e.printStackTrace();}return true;}protected void onLayout(boolean changed, int left, int top, int right,int bottom) {super.onLayout(changed, left, top, right, bottom);// 摆放位置layoutContent(false);}private void layoutContent(boolean isOpen) {// 摆放前ViewRect frontRect = computeFrontViewRect(isOpen);mFrontView.layout(frontRect.left, frontRect.top, frontRect.right, frontRect.bottom);// 摆放后ViewRect backRect = computeBackViewViaFront(frontRect);mBackView.layout(backRect.left, backRect.top, backRect.right, backRect.bottom);// 调整顺序, 把mFrontView前置bringChildToFront(mFrontView);}private Rect computeBackViewViaFront(Rect frontRect) {int left = frontRect.right;return new Rect(left, 0, left + mRange, 0 + mHeight);}private Rect computeFrontViewRect(boolean isOpen) {int left = 0;if(isOpen){left = -mRange;}return new Rect(left, 0, left + mWidth, 0 + mHeight);}protected void onFinishInflate() {super.onFinishInflate();// 当xml被填充完毕时调用mBackView = getChildAt(0);mFrontView = getChildAt(1);}protected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);mHeight = mFrontView.getMeasuredHeight();mWidth = mFrontView.getMeasuredWidth();mRange = mBackView.getMeasuredWidth();}}

android_99_自定义View_侧滑删除相关推荐

  1. 自定义view实现侧滑删除功能

    今天我们准备做侧滑删除的自定义视图,我采用了v4包里面ViewDragHelper.2013年谷歌i/o大会上介绍了两个新的layout: SlidingPaneLayout和DrawerLayout ...

  2. Android自定义ListView实现仿微信侧滑删除

    经常在遇到问题第一时间都会在网上搜索解决的方法,因此看到很多前辈们的比较精辟的技术文章,学习了很多东西,现在将自己平时工作中开发的一些小功能坐下总结,也写出来,既方便自己理清思路记忆功能块实现思路,又 ...

  3. 自定义UITableview自带侧滑删除按钮样式 by 徐

    效果如下: 实现原理: 1.打开tableview自带的侧滑删除功能 核心代码: 1 -(void)tableView:(UITableView *)tableView commitEditingSt ...

  4. 鸿蒙 github harmony,鸿蒙HarmonyOS三方件开发指南-SwipeLayout侧滑删除

    1. SwipeLayout组件功能介绍 1.1.功能介绍: SwipeLayout组件是一个侧滑删除组件. 1.2. 模拟器上运行效果: 2. SwipeLayout使用方法 2.1. 新建工程,增 ...

  5. android viewpager嵌套侧滑删除listview冲突问题

    场景:  viewpager嵌套侧滑删除的listview(如SwipeMenuListView),当在滑动在SwipeMenuListView的viewpager页时,两者滑动冲突 解决:自定义li ...

  6. android 仿微信侧滑删除SwipeListView实例

    原帖地址:http://www.eoeandroid.com/thread-540337-1-1.html Android微信5.0以前某个版本(具体哪个忘记了)实现了和IOS上面一样的效果--侧滑删 ...

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

    使用几个月的IOS之后,发现IOS中侧滑删除俺就 大家好,自己开始学习Android已经差不多半年了吧,前前后后看了不少的博客获益匪浅.渐渐的随着技术的提升,慢慢感觉网上其它的一些功能的实现又不是那么 ...

  8. Android之侧滑删除RecyclerView

    前段时间做项目,有一个需求是需要做一个侧滑删除的功能. 之前由于项目赶的比较紧,所以一起工作的小伙伴用了第三方的,自己想想,这个应该不难实现. 废话不多说,先上效果图 今天权当做下笔记,这篇文章主要参 ...

  9. 【Android】毫无耦合性,一个Item根布局搞定 item侧滑删除菜单,像IOS那样简单的使用侧滑删除。

    重要的话 开头说,not for the RecyclerView or ListView, for the Any ViewGroup. 本控件不依赖任何父布局,不是针对 RecyclerView. ...

  10. 仿QQ侧滑删除ListView——2015第一博

    一直感觉QQ最近联系人那个侧滑删除功能挺高大上的,经过几经波折,终于在新的一年里实现了该功能.实现这个功能真是费了老劲了,好几次有了想法,兴奋的去写代码实现,结果让代码打了自己一个耳光,最终还是用ma ...

最新文章

  1. 转换字符串中汉字为其拼音缩写(C#)
  2. apple id无法创建_我如何为我的Apple收藏夹创建网站
  3. Fork 一个仓库并同步
  4. Caused by: java.lang.NoSuchMethodException: onClick_Flashlight [class android.view.View]
  5. idea创建maven的web项目
  6. Linux 上安装 SQL Server
  7. pythonif语句的多分支使用_Python多分支if语句的使用
  8. 在 PowerPoint 2016 中嵌入网页
  9. 只能是做的HTML5审批流项目
  10. (王道408考研操作系统)第四章文件管理-第一节6:文件基本操作
  11. linux mysql root用户密码_Linux下修改Mysql的用户(root)的密码
  12. easyUI表单验证扩展
  13. Linux命令行安装图形化界面
  14. 认知神经科学技术革命
  15. 关于antd table展开行expandable的坑和解决办法
  16. 写给程序员的心理学入门知识(一)
  17. CF 934D 数学 推导多项式展开
  18. 爱的台阶之危险流浪者
  19. iPhone 检测 iPhone X 设备的几种方式和分辨率终极指南
  20. 怎么给word文档注音_Word文档中,怎样全篇加注拼音?

热门文章

  1. STM32 FreeRTOS 在线升级跳转时需关闭SysTick
  2. 茶觉 | 林先生的“突破”
  3. 使用echarts实现四象限做位置管理
  4. 基于SSM+Vue的少儿编程在线学习系统的设计与实现Java少儿编程管理系统(源码调试+讲解+文档)
  5. SO逆向入门实战教程三:V2-Sign
  6. 《软件工程》 团队项目展示
  7. 不懂做计划,团队全拉垮?聪明的管理者都是这样做计划管理
  8. Substrate 为区块链创新而来
  9. Excel——年终奖个人所得税
  10. SDC RPC到Kafka