10.侧拉删除

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

activity_main
  1. <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条目
  1. <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
  1. /**
     * 侧拉删除控件
     * @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:静态导入
  1. 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
  1. 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));
    		
    		
    	}
    }
    



原文地址:https://www.cnblogs.com/sixrain/p/5041947.html