android - 将 Android 的 SlidingPaneLayout 与 ViewPager 结合使用

标签 android android-viewpager slidingpanelayout

我正在尝试将 SlidingPaneLayout 与 ViewPager 一起使用,就像这样

<?xml version="1.0" encoding="utf-8"?>

<android.support.v4.widget.SlidingPaneLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/scientific_graph_slidingPaneLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <!--
         The first child view becomes the left pane.
    -->

    <ListView
            android:id="@+id/left_pane"
            android:layout_width="240dp"
            android:layout_height="match_parent"
            android:layout_gravity="left" />
    <!--
         The second child becomes the right (content) pane.
    -->

    <android.support.v4.view.ViewPager
            android:id="@+id/scientific_graph_viewPager"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    </android.support.v4.view.ViewPager>

</android.support.v4.widget.SlidingPaneLayout>

当我从左边缘拉动时,SlidingPaneLayout 会滑动;但是,当我从右边缘拉出时,我似乎无法让 ViewPager 滑动。当我从右边缘拉动时,它滑动很小,然后弹回。

这样做有可能吗?有更好的方法吗?

我发现通过向上和向左移动我的手指,我可以滑动 View 寻呼机。

最佳答案

根本原因是#onInterceptTouchEvent 的实现。 SlidingPaneLayout 的旧实现调用了#canScroll,它将检查触摸目标是否可以滚动,如果可以,将滚动触摸目标而不是滑动面板。最近的实现看起来总是拦截运动事件,一旦拖动阈值超过斜率,除了 X 拖动超过斜率和 Y 拖动超过 X 拖动的情况(如 OP 所述)。

对此的一种解决方案是复制 SlidingPaneLayout 并进行一些更改以使其正常工作。这些变化是:

  1. 修改#onInterceptTouchEvent 中的 ACTION_MOVE 案例以同时检查#canScroll,

    if (adx > slop && ady > adx || 
        canScroll(this, false, Math.round(x - mInitialMotionX), Math.round(x), Math.round(y)))
    { ... }
    
  2. 将 #canScroll 中的最终检查修改为特例 ViewPager。这种修改也可以通过覆盖#canScroll 在子类中完成,因为它不访问任何私有(private)状态。

    protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
        ...
        /* special case ViewPagers, which don't properly implement the scrolling interface */
        return checkV && (ViewCompat.canScrollHorizontally(v, -dx) ||
            ((v instanceof ViewPager) && canViewPagerScrollHorizontally((ViewPager) v, -dx)))
    }
    
    boolean canViewPagerScrollHorizontally(ViewPager p, int dx) {
        return !(dx < 0 && p.getCurrentItem() <= 0 ||
            0 < dx && p.getAdapter().getCount() - 1 <= p.getCurrentItem());       
    }
    

通过修复 ViewDragHelper 可能有更优雅的方法来执行此操作,但这是 Google 应该在未来的支持包更新中解决的问题。上面的 hack 应该让布局现在与 ViewPagers(和其他水平滚动容器?)一起工作。

关于android - 将 Android 的 SlidingPaneLayout 与 ViewPager 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17490899/

相关文章:

android - 替换 ViewPager 中的 fragment - 获取 NPE

android - 查看寻呼机,其中上一个和下一个项目尺寸较小,并具有无限滚动功能

android - 展开时如何限制AndroidSlidingUpPanel的高度

安卓 : Speeding up multiple small file downloads

android - 获取用于调整视频大小的元数据信息

android - 数据库全局实例

android - 如何在onLoadFinish 回调方法中提交FragmentPagerAdapter 中的Fragment 事务?

android - 重复的 id,标签为空,带有 androidx.navigation.fragment.NavHostFragment 的另一个 fragment

android - 如何将 SlidingPaneLayout 的 Listview 部分的宽度设置为 100%

android - SlidingPaneLayout setCoveredFadeColor () 和 setSliderFadeColor()