更改 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 滑动方向的主要内容,如果未能解决你的问题,请参考以下文章