用法:
<com.example.administrator.myapplication.GestureDemoView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="80dp">
// 该布局内写条目业务逻辑
<LinearLayout
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="80dp"
/>
// 该布局内写条目侧滑业务逻辑
<LinearLayout
android:gravity="center"
android:layout_width="100dp"
android:layout_height="match_parent"
android:background="#666999"/>
</com.example.administrator.myapplication.GestureDemoView>
/**
* Created by Administrator on 2020/2/24.
*/
public class GestureDemoView extends LinearLayout {
private GestureDetector gestureDetector;
private Scroller scroller;
/** Explain : 侧滑模块的宽度
* @author LiXiang create at 2020/2/24 21:51*/
private int MAX_SCROLL_EXTENT;
public GestureDemoView2(Context context) {
super(context);
}
public GestureDemoView2(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public GestureDemoView2(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public GestureDemoView2(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
scroller = new Scroller(context, new LinearInterpolator());
gestureDetector = new GestureDetector(context,simpleOnGestureListener);
}
GestureDetector.SimpleOnGestureListener simpleOnGestureListener = new GestureDetector.SimpleOnGestureListener(){
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
int scaleX = getScrollX();
/** Explain : 获取当前剩下的右侧滑动距离
* @author LiXiang create at 2020/2/24 21:51*/
int surplusRightScrolldistance = MAX_SCROLL_EXTENT - scaleX;
/** Explain : 获取当前剩下的左侧滑动距离
* @author LiXiang create at 2020/2/24 21:51*/
int surplusLeftScrolldistance = - scaleX;
/** Explain : 设定右侧阈值:当滑动距离大于剩余部分时,就设定为当前剩余值
* @author LiXiang create at 2020/2/24 21:55*/
if (distanceX > surplusRightScrolldistance) {
distanceX = surplusRightScrolldistance;
}else if (distanceX < surplusLeftScrolldistance){
/** Explain : 设定左侧阈值:当滑动距离小于负剩余部分时,就设定为当前剩余值
* @author LiXiang create at 2020/2/24 21:55*/
distanceX = surplusLeftScrolldistance;
}
scrollBy((int)distanceX,0);
return true;
}
/** Explain : 往左抛往左滑动,往右抛往右滑动
* @author LiXiang create at 2020/2/24 21:56*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (velocityX < 0){
rightScroll();
}else {
leftScroll();
}
return true;
}
};
private void leftScroll() {
scroller.startScroll(getScrollX(),0,-getScrollX(),0);
invalidate();
}
private void rightScroll() {
scroller.startScroll(getScrollX(),0,MAX_SCROLL_EXTENT-getScrollX(),0);
invalidate();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
/** Explain : 监听抬起动作,以最大宽度的一半为阈值点
* @author LiXiang create at 2020/2/24 21:57*/
gestureDetector.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_UP) {
if (getScrollX()>MAX_SCROLL_EXTENT/2) {
rightScroll();
}else {
leftScroll();
}
return true;
}
return super.onTouchEvent(event);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View childAt = getChildAt(i);
measureChild(childAt,widthMeasureSpec, heightMeasureSpec);
if (i==1) {
/** Explain : 侧滑模块的宽度
* @author LiXiang create at 2020/2/24 21:57*/
MAX_SCROLL_EXTENT = childAt.getMeasuredWidth();
}
}
}
/** Explain : 实现剩余部分的自动滑动
* @author LiXiang create at 2020/2/24 21:58*/
@Override
public void computeScroll() {
super.computeScroll();
if (scroller.computeScrollOffset()) {
scrollTo(scroller.getCurrX(),scroller.getCurrY());
postInvalidate();
}
}
}
Interpolator插值器