版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
当前项目需要使用该效果,但是网上能找到的大多是封装好的RecyclerView的item。
本文参考 https://blog.csdn.net/lilu_leo/article/details/7415618
和 https://blog.csdn.net/u012728458/article/details/50747280
实现。
效果:
可以看到,只有当滑到最右边时才会接单成功,否则会回弹。
先是自定义控件:复制粘贴即可
public class SlideRightViewDragHelper extends LinearLayout { private ViewDragHelper viewDragHelper; private View child; private Point childPosition = new Point(); private Point childEndPosition = new Point(); private OnReleasedListener onReleasedListener; private int oldX; private int screenWidth;//屏幕宽 public SlideRightViewDragHelper(Context context, AttributeSet attrs) { super(context, attrs); screenWidth = getResources().getDisplayMetrics().widthPixels;//获取屏幕宽 //新建viewDragHelper ,viewGroup, 灵敏度,回调(子view的移动) viewDragHelper = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() { @Override public boolean tryCaptureView(View child, int pointerId) { return true; } @Override public int clampViewPositionHorizontal(View child, int left, int dx) { oldX = left; return Math.max(0, left); } @Override public void onViewReleased(View releasedChild, float xvel, float yvel) { //只有滑动到距离右边100dp时才执行,否则回弹 if (oldX > screenWidth - 100) { viewDragHelper.settleCapturedViewAt(childEndPosition.x, childEndPosition.y); invalidate(); //必须刷新,因为其内部使用的是mScroller.startScroll,所以别忘了需要invalidate()以及结合computeScroll方法一起。 if (onReleasedListener != null) onReleasedListener.onReleased(); } else { viewDragHelper.settleCapturedViewAt(childPosition.x, childPosition.y); //反弹 invalidate(); } super.onViewReleased(releasedChild, xvel, yvel); } }); } @Override protected void onFinishInflate() { super.onFinishInflate(); child = getChildAt(0); } @Override //用viewDragHelper拦截-true public boolean onInterceptTouchEvent(MotionEvent ev) { return viewDragHelper.shouldInterceptTouchEvent(ev); } @Override //viewDragHelper拦截事件 public boolean onTouchEvent(MotionEvent event) { viewDragHelper.processTouchEvent(event); return true; } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); //定位一开始的坐标 childPosition.x = child.getLeft(); childPosition.y = child.getTop(); //滑动成功后定位坐标 childEndPosition.x = child.getRight(); childEndPosition.y = child.getTop(); } @Override public void computeScroll() { super.computeScroll(); if (viewDragHelper.continueSettling(true)) { invalidate(); } } public void setOnReleasedListener(OnReleasedListener onReleasedListener) { this.onReleasedListener = onReleasedListener; } public interface OnReleasedListener { void onReleased(); } }
接下来就是在布局中引入自定义控件。
主要布局如下——FrameLayout下有两个子布局,第一个在底部,第二个在顶部(需要滑动的布局)
<FrameLayout android:layout_width="match_parent" android:layout_height="100dp"> <!--底部布局--> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/colorPrimary" android:gravity="center_vertical" android:text=" √" android:textColor="#FFFFFFFF" android:textSize="50dp" /> <!--要滑动的布局--> <view.SlideRightViewDragHelper android:id="@+id/swipe_right" android:layout_width="match_parent" android:layout_height="100dp"> <!--里边放你的布局,这里演示直接放一个图片--> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitXY" android:src="@drawable/ic_hahaha" /> </view.SlideRightViewDragHelper> </FrameLayout>
最后:布局完成后。
需要在Activity中声明并绑定监听事件——用于在滑动后跳转
public class MainActivity extends AppCompatActivity { SlideRightViewDragHelper swipe_right; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); swipe_right = findViewById(R.id.swipe_right); swipe_right.setOnReleasedListener(new SlideRightViewDragHelper.OnReleasedListener() { @Override public void onReleased() { Log.d("右滑", "到底"); //跳转 startActivity(new Intent(MainActivity.this, Main2Activity.class)); } }); }两行代码,实现,So easy!