更改 viewPager 滑动方向

Posted

技术标签:

【中文标题】更改 viewPager 滑动方向【英文标题】:Changing viewPager swipe direction 【发布时间】:2015-12-03 07:09:14 【问题描述】:

我正在使用 TabLayout 和 viewPager 以及向左或向右滑动 viewPager 以在页面之间导航的选项。

我的问题是,我的应用程序是基于 RTL 的(从右到左)并且滑动方向是相反的。

我正在尝试将滑动方向从默认更改为反向版本。 我在网上搜索了很多,但找不到方法。

我正在使用android.support.v4.view.ViewPager;

这就是我使用 viewPager 初始化 TabLayout 的方式:

// View Page Adapter
        final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
        final PagerAdapter adapter = new PagerAdapter
                (getSupportFragmentManager(), tabLayout.getTabCount());
        //View Page Adapter Configuration
        viewPager.setAdapter(adapter);
        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
        viewPager.setOffscreenPageLimit(3);
        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() 
            @Override
            public void onTabSelected(TabLayout.Tab tab) 
                viewPager.setCurrentItem(tab.getPosition());
            

总结:目前,当我向左滑动 viewPager 时,它会显示下一页。 在 RTL 中,当您向右滑动 viewPager 时,它会显示下一页。

这可能很难理解,但就是这样。 向右滑动显示下一页

而我需要向右滑动才能显示上一页

【问题讨论】:

这不只是将PagerAdapter的内容倒序排列的问题吗? 为什么不将当前项目设置为最后一项? @CommonsWare 当我向左滑动时会发生什么?我不需要为此更改 onScrollListener 吗? (克里斯的回答相同)我需要更改 viewPager 滚动方向(向右滑动 - 下一页,向左滑动 - 上一页)。现在它颠倒了。如果我选择一个,这些选项卡效果很好。 viewPager 滑动不会。 "当我向左滑动时会发生什么?" - 向左滑动时通常会发生什么。根据您的编辑,反转 PagerAdapter 的内容似乎是您想要的。 ViewPager 中确实没有“下一页”或“上一页”的概念,因为它只关心页面索引值。由您来订购 PagerAdapter 的内容,以便“下一页”表示您想要的内容。这也可能意味着您需要根据 Chris 的评论在末尾设置起始页索引,具体取决于您希望起始状态是什么。 @CommonsWare 我想你误解了我的问题,或者我没有解释我需要什么好的。我用新信息编辑了我给你的评论答案,希望你能理解。 【参考方案1】:

改变Viewpager的滑动方向是非常简单的技术。

有两个简单的步骤必须跟随你,

1.改变View pager的旋转,

viewpager.setRotationY(180);

2.然后再改变viewpager的子片段容器的方向,

recyclerView.setRotationY(180);

注意:在我的例子中,我使用 recyclerview 作为视图寻呼机的子级。

这对我来说是 100% 的。

【讨论】:

这会反转 viewpager 中的所有视图 因为您可能只旋转了一次布局。你必须旋转两次。一旦父布局比子布局。当然,它会正常工作。 任何想法如何将 PagerTitleStrip 中的文本旋转回正常在旋转视图两次时得到预期的行为....但是旋转 180 时的寻呼机标题条仅切换标题条而不是文本的父视图方向 此解决方案工作正常,但在某些华为设备上,这会导致白屏,但回收站视图项目仍然可点击但不可见 Idk 为什么但它发生在我身上,当我删除 setRotationY 它的作品 此解决方案在 Android P 设备上存在问题。【参考方案2】:

我在一个月前遇到了同样的问题,但我认为我找到了一个很好的解决方案。 1)在xml中将您的TabLayout方向更改为ltr:

<android.support.design.widget.TabLayout
    android:id="@+id/tl_activity_main"
    android:layout_below="@id/toolbar_activity_main"
    android:layoutDirection="ltr"
    android:layout_
    android:layout_
    style="@style/DisionTabLayout" />

2) 为 ViewPager 创建自定义适配器并覆盖方法 getItem(int position) 和 getPageTitle(int position):

@Override
public Fragment getItem(int position) 
    if (mIsRtlOrientation && mTabs != null && mTabs.length > 0) 
        return mTabs[mTabs.length - position - 1].getFragment();
     else 
        return mTabs[position].getFragment();
    


@Override
public int getCount() 
    return mTabs.length;


@Override
public CharSequence getPageTitle(int position) 
    if (mIsRtlOrientation && mTabs != null && mTabs.length > 0) 
        return mTabs[mTabs.length - position - 1].getTitle();
     else 
        return mTabs[position].getTitle();
    

3) 将适配器设置为 ViewPager,然后将此 ViewPager 应用到 TabLayout。

private void setAdapters() 
    // initialize adapter
    mTabsAdapter = new TabsAdapter(getSupportFragmentManager(), mTabs, true);
    // set adapter to ViewPager
    vp.setAdapter(mTabsAdapter);
    // set ViewPager to TabLayout
    tl.setupWithViewPager(vp);
    // if RTL orientation, go to last item
    vp.setCurrentItem(vp.getAdapter().getCount() - 1, false);

4) 我创建了一篇博文,其中包含更多详细信息和完整代码 - here

【讨论】:

【参考方案3】:

我知道已经晚了,但这是一个聪明的问题。正如@CommonsWare 所说,这是在页面适配器的 getItem() 方法中颠倒项目顺序的问题。但这还不够。当您颠倒 getitem() 方法中的顺序时,您也不应该颠倒 getPageTitle() 方法中的顺序。像这样:

public static class AppSectionsPagerAdapter extends FragmentStatePagerAdapter 
        public AppSectionsPagerAdapter(FragmentManager fm) 
            super(fm);
        

        @Override
        public Fragment getItem(int position) 
            switch (position) 
                case 0:
                    return new page1();
                case 1:
                    return new page2();
                case 2:
                    return new page3();
            
        

        @Override
        public CharSequence getPageTitle(int position) 
            switch (position) 
                case 0:
                    return "page 3 title";
                case 1:
                    return "page 2 title";
                case 2:
                    return "page 1 title";
                
        

        @Override
        public int getCount() 
            return 3;
        
    

现在是棘手的部分。你应该使用这个简单的方法,它使用最大索引和当前索引来转换从零开始的索引顺序。

public int calculateReverse(int maxIndex,int currentIndex)
        return maxIndex-currentIndex;
    

你应该像这样在 onTabSelected() 中使用这个方法:注意你应该使用你自己的最大索引:

@Override
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) 
        mViewPager.setCurrentItem(calculateReverse(2,tab.getPosition()));
    

第二部分是更改页面适配器上的页面侦听器。再次,您应该使用自己的最大索引号:

mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() 
            @Override
            public void onPageSelected(int position) 
                actionBar.setSelectedNavigationItem(calculateReverse(2,position));  // reversing the tab selection
            
        );

我尽量做到描述性强。希望这会有所帮助:)

【讨论】:

【参考方案4】:

如果您将 viewpager2 与片段一起使用。你可以使用。

<androidx.viewpager2.widget.ViewPager2
        android:id="@+id/pager"
        android:layout_
        android:layout_
        **android:orientation="vertical"**
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

我希望这对某人有所帮助。

【讨论】:

【参考方案5】:

你可以使用 ViewPager2,它支持从右到左的方向。使之成为可能:

    在应用清单中添加 android:supportsRtl="true" 使viewpager2的父viewgroup布局方向ltr(android:layoutDirection="ltr") 现在设置 viewpager2 的 layoutDirection ltr (android:layoutDirection="rtl") 还将适配器的布局设置为 layoutDirection ltr (android:layoutDirection="ltr")

【讨论】:

【参考方案6】:

所以我发现最简单的方法适用于 ViewPager (1) 只是将项目数组反转,然后在显示之前将寻呼机的当前项目设置在 [array size] 位置。

【讨论】:

以上是关于更改 viewPager 滑动方向的主要内容,如果未能解决你的问题,请参考以下文章

处理导航抽屉内的 ViewPager 滑动

ViewPager2嵌套RecyclerView滑动冲突解决办法

判断viewpager左右滑动方向

以编程方式滑动时更改 ViewPager2 滚动速度

ViewPager 更改可见性后无法滑动

以编程方式滑动时更改ViewPager动画持续时间