10.侧拉删除

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

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=".MainActivity" >
 <ListView
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:id="@+id/lv"
 ></ListView>
</RelativeLayout>

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

这个其实就是adapter条目
 
 <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

/**
 * 侧拉删除控件
 * @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:静态导入
 
 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

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));
 }
}
 

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

扫码关注云+社区

领取腾讯云代金券