使用ViewDragHelper 实现吸边效果
来源:互联网 发布:凡科建站域名绑定 编辑:程序博客网 时间:2024/04/27 20:38
由于项目需求需要按钮吸边,就自己动手写了下。对于通过手势拖拽我立马就想到了ViewDragHelper这个系统工具类。有了这个类的存在 我们只需要处理松开手指的逻辑处理和边界控制就行了。
下面是实现代码
public class SuctionSideView extends RelativeLayout { private final String TAG = "SuctionSideView"; private ViewDragHelper mDragHelper; // 拖拽控制 private View mSuctionView; // 要吸边的view private Point mAutoBackOriginPos = new Point(); // 记录子view现在的位置 private boolean isInit = false; /** * 1 | 2 * ----- * 3 | 4 */ private int centerX;// 屏幕中心的x值 private int centerY;// 屏幕中心的y值 根据这两个属性建立直角坐标系 public SuctionSideView(@NonNull Context context) { super(context,null); } public SuctionSideView(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); addListener(); } /** * 初始化布局 * @throws Exception */ private void init() { } /** * 监听事件注册 */ private void addListener() { mDragHelper = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() { @Override public boolean tryCaptureView(View child, int pointerId) { return child == mSuctionView; } @Override public int clampViewPositionHorizontal(View child, int left, int dx) { final int leftBound = getPaddingLeft() + UIUtil.dp2px(10); final int rightBound = getWidth() - child.getWidth() - leftBound - UIUtil.dp2px(10); final int newLeft = Math.min(Math.max(left, leftBound), rightBound); return newLeft; } @Override public int getViewHorizontalDragRange(View child) { return getMeasuredWidth() - child.getMeasuredWidth(); } @Override public int clampViewPositionVertical(View child, int top, int dy) { final int topBound = getPaddingTop() + UIUtil.dp2px(10); final int bottomBound = getHeight() - child.getHeight() - getPaddingBottom() - UIUtil.dp2px(10); final int newTop = Math.min(Math.max(top,topBound),bottomBound); return newTop; } @Override public int getViewVerticalDragRange(View child) { return getMeasuredHeight() - child.getMeasuredHeight(); } @Override public void onViewReleased(View releasedChild, float xvel, float yvel) { if (releasedChild == mSuctionView) { if (releasedChild.getLeft() < centerX) { // 往左移动 moveTo(UIUtil.dp2px(10) + getPaddingLeft(), releasedChild.getTop()); } else { // 往右 moveTo(getWidth() - UIUtil.dp2px(59) - getPaddingRight(), releasedChild.getTop()); }// if (releasedChild.getLeft() < centerX && releasedChild.getTop() < centerY) { // 1象限// if (releasedChild.getLeft() < releasedChild.getTop()) { // 往左// moveTo(0, releasedChild.getTop());// } else { // 网上// moveTo(releasedChild.getLeft(), 0);// }// } else if (releasedChild.getLeft() > centerX && releasedChild.getTop() < centerY) { // 2象限// if (getWidth() - releasedChild.getLeft() - getWidth() < getTop() - releasedChild.getHeight()) { // 往右// moveTo(getWidth() - releasedChild.getWidth() - getPaddingRight(), releasedChild.getTop());// } else { // 往上// moveTo(releasedChild.getLeft(), 0);// }// } else if (releasedChild.getLeft() < centerX && releasedChild.getTop() > centerY) { // 3 象限// if (releasedChild.getLeft() < getHeight() - releasedChild.getTop() - releasedChild.getHeight()) { // 往左// moveTo(0, releasedChild.getTop());// } else { // 往下// moveTo(releasedChild.getLeft(), getHeight() - releasedChild.getHeight() - getPaddingBottom());// }// } else if (releasedChild.getLeft() > centerX && releasedChild.getTop() > centerY) { // 4象限// if (getWidth() - releasedChild.getLeft() - releasedChild.getWidth() < getHeight() - releasedChild.getTop() - releasedChild.getHeight()) { // 向右// moveTo(getWidth() - releasedChild.getWidth() - getPaddingRight(), releasedChild.getTop());// } else { // 往下// moveTo(releasedChild.getLeft(), getHeight() - releasedChild.getHeight() - getPaddingBottom());// }//// } ViewCompat.postInvalidateOnAnimation(SuctionSideView.this); } } }); } private void moveTo(int xvel, int yvel) { mAutoBackOriginPos.x = xvel; mAutoBackOriginPos.y = yvel; mDragHelper.smoothSlideViewTo(mSuctionView,xvel,yvel); } @Override protected void onFinishInflate() { super.onFinishInflate(); mSuctionView = getChildAt(0); LogUtil.i(TAG,"onFinishInflate"); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { centerX = getWidth() / 2; centerY = getHeight() / 2; if (!isInit) { mAutoBackOriginPos.x = getWidth() - UIUtil.dp2px(59); mAutoBackOriginPos.y = getHeight() - UIUtil.dp2px(75); isInit = true; mSuctionView.layout(mAutoBackOriginPos.x,mAutoBackOriginPos.y,mAutoBackOriginPos.x + UIUtil.dp2px(49),mAutoBackOriginPos.y + UIUtil.dp2px(65)); LogUtil.i(TAG,"mAutoBackOriginPos.x:" + mAutoBackOriginPos.x + "mAutoBackOriginPos.y" + mAutoBackOriginPos.y); } } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return mDragHelper.shouldInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { mDragHelper.processTouchEvent(event); return false; } @Override public void computeScroll() { if (mDragHelper.continueSettling(true)) { invalidate(); } }}
这里面记录下吸边控件的初始位置。
clampViewPositionHorizontal与clampViewPositionVertical这是控制吸边控件的上下左右能够活动位置
由于我的项目中值需要左右吸边所以我在
onViewReleased 里只需要判断当前控件的left超过中心线了没
其中涉及到的数字为吸边控件距左距右和控件本身的尺寸,整个代码差不多100行是不是很简单吧。
使用也非常简单 用自定义好的控件包裹住需要被吸边的控件
<cn.missfresh.home.widget.SuctionSideView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/title_bar"> <ImageView android:id="@+id/view" android:layout_width="49dp" android:layout_height="65dp" android:layout_gravity="right|bottom" android:layout_marginBottom="10dp" android:layout_marginRight="10dp" android:scaleType="fitXY" android:visibility="gone" /> </cn.missfresh.home.widget.SuctionSideView>
0 0
- 使用ViewDragHelper 实现吸边效果
- 使用ViewDragHelper实现上拉效果
- 使用ViewDragHelper实现的DragLayout开门效果
- 使用ViewDragHelper实现上拉或侧拉效果
- Android开发:使用ViewDragHelper实现抽屉拉伸效果
- 使用ViewDragHelper实现slidemenu
- android ViewDragHelper 实现抽屉滑动效果
- ViewDragHelper实现QQ条目侧滑效果
- Android ViewDragHelper实现 侧滑删除效果
- ViewDragHelper实现QQ侧滑效果
- android 使用ViewDragHelper轻松实现DrawerLayout和SlidMenu侧滑效果
- Android 使用ViewDragHelper实现向slidingMenu侧滑菜单的效果
- Android开发之使用ViewDragHelper实现侧边栏滑动的效果
- 使用 ViewDragHelper 实现左右侧滑
- ViewDragHelper 使用
- ViewDragHelper 使用
- ViewDragHelper使用
- ViewDragHelper 使用
- Java 注解原理
- 深入浅出 RPC
- 机器分配
- 写博客的缘由
- (ssl1463)公共子串
- 使用ViewDragHelper 实现吸边效果
- 关于B站播放器ijkPlayer的集成和遇到的bug(持续回复解答,ios)(QQ:479069761)
- Android开发异常:com/android/dx/command/dexer/Main : Unsupported major.minor version 52.0
- innodb和myisam引擎 ——索引实现方式差异
- 值得推荐的C/C++框架和库 (真的很强大)
- 获取网络连接状态的代码
- 梅森素数的判定(Lucas-Lehmer判定法 和 miller
- ubuntu sendmail配置
- 【APACHE MINA2.0开发之一】搭建APACHE MINA框架并实现SERVER与CLIENT端的简单消息传递!