【问题标题】:How to reverse viewpager swiping如何反向浏览器滑动
【发布时间】:2017-10-12 16:05:30
【问题描述】:

所以我的应用在 RTL 中,因此,选项卡现在从右到左排序..!

..但是当我在标签之间滑动时,它与常识相矛盾,所以我想反转它..!看图看问题..!

我想要的是..! > 当我在 Tab1 中然后从左向右滑动时,我希望它滑动到 Tab 2 等等..!

这可能……!?

代码


我的客户浏览页面

public class CustomViewPager extends android.support.v4.view.ViewPager{
private boolean enabled;

public CustomViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.enabled = true;
}


@Override
public boolean onTouchEvent(MotionEvent event) {
    if (this.enabled) {
        return super.onTouchEvent(event);
    }

    return false;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    if (this.enabled) {
        return super.onInterceptTouchEvent(event);
    }

    return false;
}

public void setPagingEnabled(boolean enabled) {
    this.enabled = enabled;
 }
 }

我的 TabActivity(助手类)

  public class TabbedActivity extends BaseActivity { 

 //I extend BaseActivity to avoid repeating UI code like toolbar and stuff..

protected CustomViewPager viewPager;
public OrdersAdapter adapter;
public TabLayout tabs;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    tabs.setTabGravity(TabLayout.GRAVITY_FILL);
    viewPager.setAdapter(adapter);
    viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabs));


    tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {

        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            setTabSelected(tab);
        }


        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });
  }


public void setTabSelected(TabLayout.Tab tab) {
    viewPager.setCurrentItem(tab.getPosition());
}

public void addTab(int title) {

    tabs.addTab(tabs.newTab().setText(getString(title)));

}

}

我的 Activity 包含 Tablayout 并具有三个片段,每个片段一个。

public class MyOrders extends TabbedActivity {

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

    tabs = (TabLayout) findViewById(R.id.tab_layout);
    addTab(R.string.NewOrderTabTitle); //tab1
    addTab(R.string.MyOrderTabTitle); // tab2
    addTab(R.string.FinOrderTabTitle); //tab3

     adapter = new OrdersAdapter(getSupportFragmentManager(), tabs.getTabCount());
    viewPager = (CustomViewPager) findViewById(R.id.pager);
    viewPager.setPagingEnabled(true);

    tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            viewPager.setCurrentItem(tab.getPosition());

        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });

    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        }

        @Override
        public void onPageSelected(int position) {

        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });

    super.onCreate(savedInstanceState);


 }
}

更新


@regev avraham

以相反的顺序添加选项卡,然后使用 viewPager.setCurrentItem(adapter.getCount() - 1); 选择最后一个 标签。

根据您的评论,这是我在具有 tablayout 的 Activity 中所做的事情

 //code...
 tabs = (TabLayout) findViewById(R.id.tab_layout);
    addTab(R.string.FinOrderTabTitle); //tab3
    addTab(R.string.MyOrderTabTitle); // tab2
    addTab(R.string.NewOrderTabTitle); //tab1
 //code...

 viewPager.setCurrentItem(adapter.getCount() - 1);

【问题讨论】:

    标签: android android-fragments android-viewpager android-tablayout swipe-gesture


    【解决方案1】:

    你可以查看这个库

    https://github.com/diego-gomez-olvera/RtlViewPager

    并实现如下

    dependencies {
    ...
    compile 'com.booking:rtlviewpager:1.0.1'
    }
    

    只需添加这个而不是 Viewpager

    <com.booking.rtlviewpager.RtlViewPager
            android:id="@+id/pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    

    【讨论】:

    • 我做不到,我不想为此使用库。我希望找到没有那个的解决方案..!
    • 谢谢。很棒的图书馆。完美运行。
    【解决方案2】:

    我在开发 RTL 应用程序时遇到了这个问题。这是做什么:

    1. 以相反的顺序添加tabs

    tabLayout.addTab(tabLayout.newTab().setText("Tab2"); tabLayout.addTab(tabLayout.newTab().setText("Tab1");

    1. 自定义ViewPager适配器以相反的顺序返回Fragments
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                Fragment2 f2 = new Fragment2();
                return f2;
            case 1:
                Fragment1 f1 = new Fragment1();
                return f1;
            default:
                return null;
        }
    }
    
    1. 选择OnCreate处的最后一个标签索引:
    TabLayout.Tab tab = tabLayout.getTabAt(1);
    tab.select();
    
    1. TabLayout的方向设置为LTR:
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        tabLayout.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
    }
    
    1. 最后,您的onTabSelected 事件应如下所示:
    public void onTabSelected(TabLayout.Tab tab) {
        viewPager.setCurrentItem(tab.getPosition());
    }
    

    效果很好。

    【讨论】:

      【解决方案3】:

      这有点棘手,android viewPager 从右到左有一个小bug,只有页面标题是从右到左,页面本身没有。

      为了解决这个问题,我所做的是使用常规的从左到右布局并以相反的顺序添加选项卡,然后使用viewPager.setCurrentItem(adapter.getCount() - 1); 选择最后一个选项卡。

      结果应该是这样的: https://drive.google.com/open?id=0B0FzrLgjet7pSE9lMFFFT0JiekE

      其中 size 是第一个选项卡,display 是第二个,依此类推

      要保持 RTL 行为和 LTR 行为,您应该使用这个:

      Configuration config = getResources().getConfiguration();
      if (config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL)
      {
           //use the RTL trick here
      }
      else
      {
           //use the regular case here
      }
      

      【讨论】:

      • 我这样做了,但它只记录了我的标签位置,并没有反转滑动。!你能告诉我要更改的代码吗?!
      • 能否请您添加您所做的工作?,此解决方案适用于我的应用程序。
      • 我用显示所需行为的视频更新了我的答案。这是你想要达到的目标吗?
      • YES.. 这正是我想要的,但我照你说的做了,但没有用,所以我很可能遗漏了一些东西,你能检查一下上面的课程,看看应该做什么被改变了,具体在哪里,我真的可以使用帮助。!
      • 您是否忘记将标签布局方向设置为从左到右而不是从右到左?
      【解决方案4】:

      如果您的minSdkVersion 是 17+,您可以对标签布局执行此操作:

      TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
      tabLayout.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
      

      【讨论】:

      • 它不起作用,当我添加这一行时没有任何变化。!
      【解决方案5】:

      现在,您可以使用类似的小部件(支持 RTL 分页滑动)以有效的方式进行操作。 它会根据系统本地自动改变滑动方向,也可以手动设置。

      Android 开发了一个名为 ViewPager2 的新小部件

      ViewPager2ViewPager 的改进版本,它提供 增强的功能并解决使用中的常见困难 ViewPager.

      您可以按照这些简单的步骤创建与TabLayout 集成的ViewPager2

      1. layout_main.xml 中使用此代码:

        <?xml version="1.0" encoding="utf-8"?>
        <androidx.coordinatorlayout.widget.CoordinatorLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        
         <com.google.android.material.appbar.AppBarLayout
             android:id="@+id/app_bar_layout"
             android:layout_width="match_parent"
             android:layout_height="wrap_content">
        
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:title="@string/app_name">
            </androidx.appcompat.widget.Toolbar>
        
            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/colorPrimary" />
        
        </com.google.android.material.appbar.AppBarLayout>
        
        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/view_pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layoutDirection="locale"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />
        
        </androidx.coordinatorlayout.widget.CoordinatorLayout>
        
      2. 创建名称为PagerAdapter的适配器类:

        public class PagerAdapter extends FragmentStateAdapter {
            public PagerAdapter(FragmentActivity fm) {
                super(fm);
            }
        
            @NonNull
            @Override
            public Fragment createFragment(int position) {
                switch (position) {
                    case 0:
                        return YourFragment1.newInstance();
                    case 1:
                        return YourFragment2.newInstance();
                }
                return null;
            }
        
            @Override
            public int getItemCount() {
                return 2;
            }
        }
        
      3. MainActivity 中(使用视图绑定从xml 文件中获取视图):

        public class MainActivity extends AppCompatActivity {
             //Tabs titles
             private static final int[] TAB_TITLES = new int[]{R.string.tab_text_1, R.string.tab_text_2};
             //Binding object
             private ActivityMainBinding binding;
        
             @Override
             protected void onCreate(Bundle savedInstanceState) {
                 super.onCreate(savedInstanceState);
                 //Inflate layout
                 binding = ActivityMainBinding.inflate(getLayoutInflater());
                 View view = binding.getRoot();
                 setContentView(view);
        
                 //Get TabLayout View
                 TabLayout tabs = binding.tabs;
                 //Get the viewPager View
                 ViewPager2 viewPager = binding.viewPager;
        
                 //Adapter for ViewPager
                 PagerAdapter pagerAdapter = new PagerAdapter(this);
                 //Set Adapter for ViewPager
                 viewPager.setAdapter(pagerAdapter);
        
                 //Integrate TabLayout with ViewPager
                 //i use it to get tabs titles
                 new TabLayoutMediator(tabs, viewPager, new TabLayoutMediator.TabConfigurationStrategy() {
                     @Override
                     public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
                         //set the title for the tab at position index
                         tab.setText(getResources().getString(TAB_TITLES[position]));
                     }
                 }).attach();
             }
        }
        

      我使用的这些资源(您可以阅读更多详细信息):

      • 从开始创建ViewPager2this link
      • ViewPager 迁移到ViewPager2this link

      希望我对此有所帮助。

      【讨论】:

        【解决方案6】:

        最简单的方法是使用这一行代码:

        tabLayout.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
        

        对于标签的 RTL 排序,您应该在寻呼机中进行:

        viewPager.setCurrentItem(adapter.getCount());
        

        感谢:arash-hatemi

        【讨论】:

          【解决方案7】:

          您可以将ViewPagerrotationY设置为180度,并将instantiateItem方法上子视图的rotationY设置为180度。

          例子:

          ViewPager viewPager = new ViewPager(context);
          viewPager.setRotationY(180F);
          viewPagerMediaViewer.setAdapter(new PagerAdapter() {
              @Override
              public int getCount() {
                  return 0;
              }
          
              @Override
              public Object instantiateItem(@NonNull ViewGroup container, int position) {
                  LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
          
                  View childView = inflater.inflate(R.layout.model_view_pager_item, container, false);
          
                  container.addView(currentView);
                  childView.setRotationY(180F);
                  return currentView;
              }
          
              @Override
              public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
                  return view == object;
              }
          
              @Override
              public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
                  container.removeView((LinearLayout)object);
              }
          });
          

          【讨论】:

          • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center