在 viewpager 上滑动时,选项卡选择器无法在上一个选项卡上单击

Tab selector not working on previous tab click when swipe on viewpager

我遵循 this 示例..

我遇到一个问题,当我在 ViewPager 上滑动时会出现相应的 fragment,但是当我从左向右或从右向左滑动时 和 select 上一个选项卡 选项卡指示器出现在新的 select 选项卡上,但相应的 fragment 未出现在 ViewPager 上。 请帮助我,我哪里错了?

这是我使用的并且工作正常。

适配器:

    public class SCFragmentPagerAdapter extends FragmentPagerAdapter {

    private final List<Fragment> mFragments = new ArrayList<>();
    private final List<String> mFragmentTitles = new ArrayList<>();

    private Context mContext;
    private FragmentManager mFragmentManager;

    public SCFragmentPagerAdapter(FragmentManager fm, Context context) {
        super(fm);
        this.mFragmentManager = fm;
        this.mContext = context;
    }

    @Override
    public int getCount() {
        return mFragments.size();
    }

    // Return the correct Fragment based on index
    @Override
    public Fragment getItem(int position) {
        return mFragments.get(position);
    }

    public void addFragment(Fragment fragment, String title) {
        mFragments.add(fragment);
        mFragmentTitles.add(title);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        // Return the tab title to SlidingTabLayout
        return mFragmentTitles.get(position);
    }


    public Fragment getActiveFragment(ViewPager container, int position) {
        String name = makeFragmentName(container.getId(), position);
        return  mFragmentManager.findFragmentByTag(name);
    }

    private static String makeFragmentName(int viewId, int index) {
        return "android:switcher:" + viewId + ":" + index;
    }

}

Activity:

public class SCWelcomeActivity extends AppCompatActivity implements
        SCWelcomeFragment.OnFragmentInteractionListener,
        SCSyncFragment.OnFragmentInteractionListener,
        SCRegisterFragment.OnFragmentInteractionListener,
        SCConfirmationFragment.OnFragmentInteractionListener {

    private static final String TAG = SCWelcomeActivity.class.getSimpleName();

    private ViewPager viewPager = null;
    private TabLayout tabLayout = null;
    private Toolbar toolbar = null;
    private SCFragmentPagerAdapter adapter = null;

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

        // Layout manager that allows the user to flip through the pages
        viewPager = (ViewPager) findViewById(R.id.viewpager);
        setupViewPager(viewPager);

        // Initialize the Sliding Tab Layout
        tabLayout = (TabLayout) findViewById(R.id.tablayout);

        // Connect the viewPager with the sliding tab layout
        tabLayout.setupWithViewPager(viewPager);
        tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }

    @Override
    public void onFragmentInteraction(Uri uri) {

    }


    private void setupViewPager(ViewPager viewPager) {

        adapter = new SCFragmentPagerAdapter(getSupportFragmentManager(), SCWelcomeActivity.this);
        adapter.addFragment(SCWelcomeFragment.newInstance(), getString(R.string.title_tab1));
        adapter.addFragment(SCSyncFragment.newInstance(), getString(R.string.title_tab2));
        adapter.addFragment(SCRegisterFragment.newInstance(), getString(R.string.title_tab3));
        adapter.addFragment(SCConfirmationFragment.newInstance(), getString(R.string.title_tab4));


        viewPager.setAdapter(adapter);
        viewPager.setOffscreenPageLimit(4);
    }

    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        public void onFragmentInteraction(Uri uri);
    }
}

片段示例:

    public class SCWelcomeFragment extends Fragment {

    private OnFragmentInteractionListener mListener;

    public static SCWelcomeFragment newInstance() {
        SCWelcomeFragment fragment = new SCWelcomeFragment();
        return fragment;
    }

    public SCWelcomeFragment() {
        super();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_scwelcome, container, false);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnFragmentInteractionListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        public void onFragmentInteraction(Uri uri);
    }
}

布局:

    <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/coordinator"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="130dp"
        android:fitsSystemWindows="true"
        android:gravity="bottom"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_collapseMode="pin"
            android:layout_gravity="center"
            android:theme="@style/ThemeOverlay.AppCompat.Dark"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tablayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />


    </android.support.design.widget.AppBarLayout>


</android.support.design.widget.CoordinatorLayout>

请像我一样尝试实现适配器。请密切注意,在我的 Adapter 中,所有实例都保存在

private final List<Fragment> mFragments = new ArrayList<>();

在你的情况下,你总是返回一个新实例。这就是设置 setOffscreenPageLimit(4) 的原因。到 4 所以它们也保存在内存中。

我有更短的变体来修复这个错误(android 支持设计库 v.23.0.0):

...
//initialize views
    mViewPager.setAdapter(pagerAdapter);
    mTabLayout.setupWithViewPager(mViewPager);
    mViewPager.clearOnPageChangeListeners();
    mViewPager.addOnPageChangeListener(new WorkaroundTabLayoutOnPageChangeListener(mTabLayout));
...

和class解决方法TabLayoutOnPageChangeListener:

public class WorkaroundTabLayoutOnPageChangeListener extends TabLayout.TabLayoutOnPageChangeListener {
    private final WeakReference<TabLayout> mTabLayoutRef;

    public WorkaroundTabLayoutOnPageChangeListener(TabLayout tabLayout) {
        super(tabLayout);
        this.mTabLayoutRef = new WeakReference<>(tabLayout);
    }

    @Override
    public void onPageSelected(int position) {
        super.onPageSelected(position);
        final TabLayout tabLayout = mTabLayoutRef.get();
        if (tabLayout != null) {
            final TabLayout.Tab tab = tabLayout.getTabAt(position);
            if (tab != null) {
                tab.select();
            }
        }
    }
}

这是支持库 23.0.0 中的错误,但已在 23.0.1 中解决。首先更新您的 支持库使用额外部分的 SDK 管理器。 并在应用 gradle 文件中写入以下行。

compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.android.support:design:23.0.1'

供大家参考

https://developer.android.com/topic/libraries/support-library/revisions.html 并阅读 Android 支持库修订版 23.0.1 部分 设计支持库的更改

在您的 activity 中,按 ID 找到视图后,您应该 "config" 您的 ViewPager 和 TabLayout。一些必要的功能可能是:ViewPager 的“addOnPageChangeListener”和 TabLayout 的“setOnTabSelectedListener”,如下所示:

public class MainActivity extends AppCompatActivity {

private final int numOfPages = 4; //viewpager has 4 pages
private final String[] pageTitle = {"Food", "Movie", "Shopping", "Travel"};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);

    for (int i = 0; i < numOfPages; i++) {
        tabLayout.addTab(tabLayout.newTab().setText(pageTitle[i]));
    }

    //set gravity for tab bar
    tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

    final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
    final PagerAdapter adapter = new PagerAdapter
            (getSupportFragmentManager(), numOfPages);

    viewPager.setAdapter(adapter);
    viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
    tabLayout.setOnTabSelectedListener(onTabSelectedListener(viewPager));
}

private TabLayout.OnTabSelectedListener onTabSelectedListener(final ViewPager pager) {
    return new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            pager.setCurrentItem(tab.getPosition());
        }

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

        }

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

        }
    };
}

我有一个关于此的教程 post,而且效果很好!没有像你这样的错误。 希望它有所帮助: http://www.devexchanges.info/2015/08/android-material-design-viewpager-with.html

您使用的支持库版本是 23.0.0 吗?有一个问题 https://code.google.com/p/android/issues/detail?id=183123 看起来与您的相似。如果确实如此,请将您的支持库版本更新为 23.0.1。此问题已修复。

None 以上答案对我有用截至 2016 结束 bug 仍然存在于设计支持库 24+. 我可以通过将选项卡布局包装在
中来解决这个问题 协调器布局