天天看點

SwipeBack側滑開源元件沖突問題處理SwipeBack側滑開源元件沖突問題處理

SwipeBack側滑開源元件沖突問題處理

SwipeBack github位址:https://github.com/zhibuyu/SwipeBackDemo

智能手機的大屏化,使得單手操作和側滑傳回這兩個功能成為了移動開發中常見的需求,本文說的就是側滑開源元件SwipeBack在常見布局中的一些沖突問題。

常見問題:

  1. Editext滑動沖突
  2. RecyclerView滑動沖突

1.Editext滑動沖突

需求場景:Editext設定單行顯示許多文字時,需要左右滑動輸入框内的文字,例如頂部搜尋輸入框。此時右滑會與側滑傳回沖突

解決方案:

使用自定義view判斷Editext何時滑動到最左端再去控制整個布局是否側滑

public class MyEditext extends android.support.v7.widget.AppCompatEditText {
private ScrollViewListener scrollViewListener = null;
private boolean can_touch;
public interface ScrollViewListener {
void onScrollChanged(MyEditext editext, int x, int y,
 int oldx, int oldy);
}
public MyEditext(Context context) {
super(context);
}

public MyEditext(Context context, AttributeSet attrs) {
super(context, attrs);
}

public MyEditext(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (getParent() != null) {
getParent().requestDisallowInterceptTouchEvent(can_touch);
}
return super.dispatchTouchEvent(ev);
}

public void setCan_touch(boolean can_touch) {
this.can_touch = can_touch;
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (scrollViewListener != null) {
scrollViewListener.onScrollChanged(this, l, t, oldl, oldt);
}
}
public void setScrollViewListener(ScrollViewListener scrollViewListener) {
this.scrollViewListener = scrollViewListener;
}
}
           

使用此自定義view時(signatureEdit為MyEditext自定義view)

核心代碼:

private boolean leftEnd;//判斷是否滑動到最左端

 signatureEdit.setScrollViewListener(new MyEditext.ScrollViewListener() {
        @Override
        public void onScrollChanged(MyEditext v, int x, int y, int oldx, int oldy) {
            if (v.getScrollX() > 0) {
                leftEnd = false;
            } else {
                leftEnd = true;
            }
        }
    });
    signatureEdit.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            EditTextOnTouch(view,event,signatureEdit,leftEnd);
            return false;
        }
    });

private void EditTextOnTouch(View view, MotionEvent event,MyEditext myEditext,boolean flag) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            break;
        case MotionEvent.ACTION_MOVE:
            if (view instanceof EditText) {
                if (flag){
                    myEditext.setCan_touch(false);
                }else {
                    myEditext.setCan_touch(true);
                }
                setEnableSwipe(flag);
            }
            break;
        case MotionEvent.ACTION_UP:
            setEnableSwipe(true);
            break;
        case MotionEvent.ACTION_CANCEL:
            setEnableSwipe(true);
            break;
    }
}
           

注釋 setEnableSwipe((boolean enableSwipe)為設定是否支援滑動傳回,上面分享的開源代碼的基類中已包含

2.RecyclerView滑動沖突

需求場景:RecyclerView滑動方向和SwipeBack滑動方向一緻,滑動出現沖突

解決方案:

同樣判斷RecyclerView何時滑動到最左端再去控制整個布局是否側滑

可以外層包一個自定義ScrollView,也可以直接判斷RecyclerView是否滑動到最左端,根據需求而定,我這是需要外層加個ScrollView

核心代碼:

自定義橫向ScrollView

public class MySwipeRecyclerView extends RecyclerView {

boolean isIntercept=true;
public MySwipeRecyclerView(Context context) {
super(context);
}

public MySwipeRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}

public MySwipeRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (getParent() != null) {
getParent().requestDisallowInterceptTouchEvent(isIntercept);
}
return super.dispatchTouchEvent(ev);
}

public void setIntercept(boolean intercept) {
isIntercept = intercept;
}
           

使用 (photoscrv為自定義ScrollView)

private boolean isleftEnd;

photoscrv.setScrollViewListener(new MyHorizontalScrollView.ScrollViewListener() {
@Override
public void onScrollChanged(MyHorizontalScrollView v, int x, int y, int oldx, int oldy) {
    if (v.getScrollX() > 0) {
        isleftEnd = false;
      } else {
         isleftEnd = true;
      }
      }
      });


 photoRecyclerview.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (v instanceof RecyclerView) {
                        setEnableSwipe(isleftEnd);
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    setEnableSwipe(true);
                    break;
                case MotionEvent.ACTION_CANCEL:
                    setEnableSwipe(true);
                    break;
            }
            return true;
        }
    });
           

3.Viewpager滑動已在源碼中處理

SwipeBack github位址:https://github.com/zhibuyu/SwipeBackDemo

繼續閱讀