转载请注明原创出处,谢谢!
- GitHub: @Ricco
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.customview.widget.ViewDragHelper;
public class MyViewDragLinearLayout extends LinearLayout {
public MyViewDragLinearLayout(@NonNull Context context) {
super(context);
init();
}
public MyViewDragLinearLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public MyViewDragLinearLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private ViewDragHelper mViewDragHelper;
private void init() {
mViewDragHelper = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() {
@Override
public boolean tryCaptureView(@NonNull View child, int pointerId) {
return true;
}
@Override
public int clampViewPositionVertical(@NonNull View child, int top, int dy) {
if (top <= 0) {
return 0;
}
return Math.min(top, getMeasuredHeight() - child.getMeasuredHeight());
}
@Override
public int clampViewPositionHorizontal(@NonNull View child, int left, int dx) {
if (left <= 0) {
return 0;
}
return Math.min(left, getMeasuredWidth() - child.getMeasuredWidth());
}
@Override
public int getViewHorizontalDragRange(@NonNull View child) {
return 1; // 返回1不影响子view的点击事件
}
@Override
public int getViewVerticalDragRange(@NonNull View child) {
return 1; // 返回1不影响子view的点击事件
}
});
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return mViewDragHelper.shouldInterceptTouchEvent(ev);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent ev) {
mViewDragHelper.processTouchEvent(ev);
// 判断触摸是否在子View的范围内,不影响底部view的时间
return mViewDragHelper.isViewUnder(getChildAt(0), (int) ev.getX(), (int) ev.getY());
}
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
<Button
android:id="@+id/btn4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="底层按钮" />
</LinearLayout>
<com.demo.MyViewDragLinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/ll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#afa"
android:orientation="horizontal"
android:padding="@dimen/dp_10">
<Button
android:id="@+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#faf"
android:text="按钮1" />
<Button
android:id="@+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#aaf"
android:text="按钮1" />
<Button
android:id="@+id/btn3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ffa"
android:text="按钮3" />
</LinearLayout>
</com.demo.MyViewDragLinearLayout>
</FrameLayout>
如果需要设置ll的开始位置,动态设置LayoutParams的topMargin和leftMargin就可以