用法:
<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插值器