zoukankan      html  css  js  c++  java
  • 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));
      		
      		
      	}
      }
      



  • 相关阅读:
    Matplotlib 使用
    谈谈 JavaScript 的正则表达式
    Sequelize 学习笔记(11)- Migrations 迁移
    影响 POST 请求文件上传失败的几个环节的配置(php + nginx)
    安装 composer 并启动 yii2 项目
    机器学习初探
    如何深拷贝一个对象数组?
    断舍离 ——《代码整洁之道》读书笔记
    moment.js 学习笔记
    postgres Date/Time 学习笔记
  • 原文地址:https://www.cnblogs.com/sixrain/p/5041947.html
Copyright © 2011-2022 走看看