前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >10.侧拉删除

10.侧拉删除

作者头像
六月的雨
发布2022-01-12 16:33:01
3490
发布2022-01-12 16:33:01
举报
文章被收录于专栏:Android开发指南

* 应用场景: 聊天列表界面,邮件管理界面等条目管理(设为已读, 删除等) * 功能实现: 参考 侧滑面板 offsetLeftAndRight , offsetTopAndBottom

activity_main

代码语言:javascript
复制
<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=".MainActivity" >
 <ListView
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:id="@+id/lv"
 ></ListView>
</RelativeLayout>
 

item_list:设置文本区域最小高度,如果不设置和设置分别是这样的

这个其实就是adapter条目

代码语言:javascript
复制
<com.itheima.swipelayout.ui.SwipeLayout 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="#44000000" >
 <LinearLayout
 android:layout_width="wrap_content"
 android:layout_height="match_parent"
 android:orientation="horizontal" >
 <TextView
 android: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" />
 <TextView
 android: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>
 <LinearLayout
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:background="#44ffffff"
 android:gravity="center_vertical"
 android:orientation="horizontal" >
 <ImageView
 android:id="@+id/iv_image"
 android:layout_width="40dp"
 android:layout_height="40dp"
 android:layout_marginLeft="15dp"
 android:src="@drawable/head_1" />
 <TextView
 android:id="@+id/tv_name"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginLeft="15dp"
 android:text="Name" />
 </LinearLayout>
</com.itheima.swipelayout.ui.SwipeLayout>
 
 

SwipeLayout

代码语言:javascript
复制
 /**
 * 侧拉删除控件
 * @author poplar
 *
 */
public class SwipeLayout extends FrameLayout {
 private Status status = Status.Close;
 private OnSwipeLayoutListener swipeLayoutListener;
 public Status getStatus() {
 return status;
 }
 public void setStatus(Status status) {
 this.status = status;
 }
 public OnSwipeLayoutListener getSwipeLayoutListener() {
 return swipeLayoutListener;
 }
 public void setSwipeLayoutListener(OnSwipeLayoutListener swipeLayoutListener) {
 this.swipeLayoutListener = swipeLayoutListener;
 }
 public static enum Status{
 Close, Open, Draging
 }
 public static interface OnSwipeLayoutListener {
 void onClose(SwipeLayout mSwipeLayout);
 void onOpen(SwipeLayout mSwipeLayout);
 void onDraging(SwipeLayout mSwipeLayout);
 // 要去关闭
 void onStartClose(SwipeLayout mSwipeLayout);
 // 要去开启,这时候需要其他开启的关闭
 void onStartOpen(SwipeLayout mSwipeLayout);
 }
 public SwipeLayout(Context context) {
 this(context, null);
 }
 public SwipeLayout(Context context, AttributeSet attrs) {
 this(context, attrs, 0);
 }
 public SwipeLayout(Context context, AttributeSet attrs, int defStyle) {
 super(context, attrs, defStyle);
 mDragHelper = ViewDragHelper.create(this, 1.0f, mCallback);
 }
 ViewDragHelper.Callback mCallback = new ViewDragHelper.Callback() {
 // c. 重写监听
 @Override
 public boolean tryCaptureView(View view, int id) {
 return true;
 }
 // 限定移动范围
 public int clampViewPositionHorizontal(View child, int left, int dx) {
 // left
 if(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. 传递触摸事件
 @Override
 public 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);
 }
 }
 @Override
 public void computeScroll() {
 super.computeScroll();
 if(mDragHelper.continueSettling(true)){
 ViewCompat.postInvalidateOnAnimation(this);
 }
 }
 @Override
 public boolean onTouchEvent(MotionEvent event) {
 try {
 mDragHelper.processTouchEvent(event);
 } catch (Exception e) {
 e.printStackTrace();
 }
 return true;
 }
 @Override
 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) {
 // 摆放前View
 Rect frontRect = computeFrontViewRect(isOpen);
 mFrontView.layout(frontRect.left, frontRect.top, frontRect.right, frontRect.bottom);
 // 摆放后View
 Rect 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);
 }
 @Override
 protected void onFinishInflate() {
 super.onFinishInflate();
 // 当xml被填充完毕时调用
 mBackView = getChildAt(0);
 mFrontView = getChildAt(1);
 }
 @Override
 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();
 }
}
 

MyAdapter:静态导入

代码语言:javascript
复制
 import static com.itheima.swipelayout.bean.Cheeses.NAMES;
public class MyAdapter extends BaseAdapter {
 protected static final String TAG = "TAG";
 public MyAdapter(Context context) {
 super();
 this.context = context;
 opendItems = new ArrayList<SwipeLayout>();
 }
 private Context context;
 private ArrayList<SwipeLayout> opendItems;
 @Override
 public int getCount() {
 return NAMES.length;
 }
 @Override
 public Object getItem(int position) {
 return NAMES[position];
 }
 @Override
 public long getItemId(int position) {
 // TODO Auto-generated method stub
 return position;
 }
 @Override
 public 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);
 SwipeLayout sl = (SwipeLayout)view;
 sl.setSwipeLayoutListener(new OnSwipeLayoutListener() {
 @Override
 public void onStartOpen(SwipeLayout mSwipeLayout) {
 Log.d(TAG, "onStartOpen");
 // 要去开启时,先遍历所有已打开条目, 逐个关闭
 for (SwipeLayout layout : opendItems) {
 layout.close();
 }
 opendItems.clear();
 }
 @Override
 public void onStartClose(SwipeLayout mSwipeLayout) {
 Log.d(TAG, "onStartClose");
 }
 @Override
 public void onOpen(SwipeLayout mSwipeLayout) {
 Log.d(TAG, "onOpen");
 // 添加进集合
 opendItems.add(mSwipeLayout);
 }
 @Override
 public void onDraging(SwipeLayout mSwipeLayout) {
 }
 @Override
 public void onClose(SwipeLayout mSwipeLayout) {
 Log.d(TAG, "onClose");
 // 移除集合
 opendItems.remove(mSwipeLayout);
 }
 });
 return view;
 }
 static class ViewHolder {
 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_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;
 }
 }
}
 

MainActivity

代码语言:javascript
复制
 public class MainActivity extends Activity {
 private static final String TAG = "TAG";
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 ListView mList = (ListView) findViewById(R.id.lv);
 mList.setAdapter(new MyAdapter(MainActivity.this));
 }
}
  
 
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015-12-12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档