2017-07-27 40 views
0

我想弄清楚什麼是最好的方式來實現兩個列表,其中父列表可以垂直滑動和兒童可以水平滑動。 父列表被假定爲無限列表,而孩子最多可以有n個頁面。 RecyclerView看起來是這項工作的最佳工具,並且由於添加了PagerSnapHelper,所以很容易重新創建頁面滑動行爲(認爲ViewPager)。 我面臨的當前問題是當我們一直水平滑動到最後或開始,有時垂直recyclerview(父)接管並更改頁面。 這甚至可以與單個垂直recyclerview被重新創建,如下所示:使用PagerSnapHelper垂直和水平RecyclerViews

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView); 

    LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false); 
    PagerSnapHelper snapHelper = new PagerSnapHelper(); 
    SearchAdapter searchAdapter = new SearchAdapter(); 

    mRecyclerView.setLayoutManager(layoutManager); 
    mRecyclerView.setAdapter(searchAdapter); 
    snapHelper.attachToRecyclerView(mRecyclerView); 
} 

甲從上到下或從下到上揮動如預期/掃視將改變的頁面。但是,如果您執行水平運動(從左到右或從右到左),則有時會發生垂直掃動。 看起來PagerSnapHelper對快速移動非常敏感。有沒有什麼辦法可以避免這個頁面在水平啓動而不是垂直啓動時發生變化?這個問題在我的案例中更引人注目,因爲我也有一個水平頁面瀏覽器。

可能的解決方案:

  • 擴展RecyclerView的控制的onTouchEvent和OnInterceptTouchEvent。還沒有想出一個方法來使用這個。
  • 使用GestureDetector

我很高興在需要時提供更多的上下文/代碼。 有兩個PagerSnapHelper可能不是Android中的當前模式,但即使我拿走那部分,我也不知道爲什麼PagerSnapHelper對某些手勢如此敏感。

+0

也許你應該覆蓋[onFling(https://開頭android.googlesource.com/platform/frameworks/support/+/refs/heads/master/v7/recyclerview/src/android/support/v7/widget/SnapHelper.java?autodive=0%2F#65)? – pskink

+0

我也研究過這個。在onFling被觸發時,方向已經被確定,並且velocityY小於或大於0,而velocityX始終爲0.我將在我的帖子上添加更多的細節。 – apSTRK

+0

因此取決於abs(速度),你可以返回'super.onFling()'或'false'? – pskink

回答

0

當父母垂直的時候我不得不尋找PagerSnapHelpers的問題,因爲垂直父母將某些水平滑動混淆爲垂直。爲了避免這種混淆,我攔截被檢測爲水平的事件並且不允許父母消費這樣的事件。 這裏是什麼,我做了一個簡單的版本:

public class VerticalRecyclerView extends RecyclerView { 

    private GestureDetector mGestureDetector; 

    public VerticalRecyclerView(Context context) { 
     super(context); 
     init(); 
    } 

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

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

    private void init() { 
     LinearLayoutManager layoutManager = new LinearLayoutManager(getContext()); 
     layoutManager.setOrientation(LinearLayoutManager.VERTICAL); 
     setLayoutManager(layoutManager); 

     mGestureDetector = new GestureDetector(getContext(), new HorizontalScrollDetector()); 
    } 

    @Override 
    public boolean onInterceptTouchEvent(MotionEvent e) { 
     if (mGestureDetector.onTouchEvent(e)) { 
      return false; 
     } 
     return super.onInterceptTouchEvent(e); 
    } 

    public class HorizontalScrollDetector extends 
      GestureDetector.SimpleOnGestureListener { 

     @Override 
     public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { 
      return Math.abs(distanceX) > Math.abs(distanceY); 
     } 

    } 
} 

他們的關鍵是,如何檢測如果滾動應考慮水平爲return Math.abs(distanceX) > Math.abs(distanceY);