先给大家看效果图吧、
需求:
将复杂的内容布局 通过向右拖拽或者是快速向右滑动将其移动到最右边
当在向左拖动或者是快速向左滑动会将移除的布局恢复到原位
使用方法
github源码 欢迎star fork https://github.com/shf981862482/SlideLayoutApp.git
compile 'com.slidelayout:slipe_layout_library:0.0.3'
//滑动完成监听
slide.setOnSlideStatusListener(new SlideLayout.OnSlideStatusListener() {
@Override
public void slideOutComplete() {
Log.d("SHF", "slideOutComplete");
}
@Override
public void slideInComplete() {
Log.d("SHF", "slideInComplete");
}
});
注意:
1、SlideLayout使用相当于RelativeLayout
2、 第一个子布局就是可拖动的布局
3、至少一个子布局
<sun.com.slipelayoutlibrary.SlideLayout
android:id="@+id/slide"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:background="@color/grayTran"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="4dp"
android:text="@string/text" />
<TextView
android:id="@+id/gone_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="消失的内容" />
</RelativeLayout>
<Button
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="改布局" />
</sun.com.slipelayoutlibrary.SlideLayout>
SlideLayout布局是结合 自定义的ViewDrawHelp来实现的
还没了解ViewDrawHelp的请看鸿祥的博客 Android ViewDragHelper完全解析 自定义ViewGroup神器
SlideViewDragHelper原理
在使用ViewDragHelper的时候、我们需要将onInterceptTouchEvent 和 onTouchEvent 交给
ViewDragHelper处理 代码如下
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return mDragger.shouldInterceptTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mDragger.processTouchEvent(event);
return true;
}
这里主要说一下 processTouchEvent
我们看一下他的部分源码
case MotionEvent.ACTION_DOWN: {
final float x = ev.getX();
final float y = ev.getY();
mCallback.onViewDown(ev);
final int pointerId = MotionEventCompat.getPointerId(ev, 0);
final View toCapture = findTopChildUnder((int) x, (int) y);
saveInitialMotion(x, y, pointerId);
// Since the parent is already directly processing this touch event,
// there is no reason to delay for a slop before dragging.
// Start immediately if possible.
tryCaptureViewForDrag(toCapture, pointerId);
final int edgesTouched = mInitialEdgesTouched[pointerId];
if ((edgesTouched & mTrackingEdges) != 0) {
mCallback.onEdgeTouched(edgesTouched & mTrackingEdges, pointerId);
}
break;
}
可以看到 在按下的时候 会通过 findTopChildUnder((int) x, (int) y); 找到需要拖动的子view
findTopChildUnder 方法源码如下
public View findTopChildUnder(int x, int y) {
final int childCount = mParentView.getChildCount();
for (int i = childCount - 1; i >= 0; i--) {
final View child = mParentView.getChildAt(mCallback.getOrderedChildIndex(i));
if (x >= child.getLeft() && x < child.getRight() &&
y >= child.getTop() && y < child.getBottom()) {
return child;
}
}
return null;
}
他是根据点击的位置来找到点击的子child,
那么当我们将布局拖出去之后,显然根据源码是找不到子view的 这个方法就会返回空,那么我们又要拖拽这个处于外头的子布局怎么办呢,看代码
public View findTopChildUnder(int x, int y) {
final int childCount = mParentView.getChildCount();
if (childCount >