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

时间:2015-07-22 05:32:39

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

我正在关注this示例..

我遇到一个问题,当我在ViewPager fragment出现相应的fragment时,但是当我从左向右或从右向左滑动并选择上一个标签时选项卡指示符显示在新选择的选项卡上,但ViewPager上未显示相应的<style>。 请帮助我,我出错了?

6 个答案:

答案 0 :(得分:5)

这是支持lib 23.0.0中的错误,但它在23.0.1中解决。首先使用SDK管理器从附加部分更新您的 suppory库。 并在app 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部分

答案 1 :(得分:4)

在您的活动中,在按ID查找视图后,您应该&#34; config&#34;您的ViewPager和TabLayout。一些必要的功能可能:&#34; addOnPageChangeListener &#34;对于ViewPager和&#34; setOnTabSelectedListener &#34;像这样的TabLayout:

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) {

        }
    };
}

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

答案 2 :(得分:3)

这是我使用和工作正常。

适配器:

    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;
    }

}

的活动:

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>

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

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

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

答案 3 :(得分:2)

上述答案均不适合我在 2016 结束时错误仍然存​​在于设计支持库24 + 中。 我能够通过将标签布局包装在一个中来解决这个问题 协调员布局

答案 4 :(得分:0)

我有更多更短的变种来修复这个bug(android support design lib v.23.0.0):

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

并且类WorkaroundTabLayoutOnPageChangeListener:

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();
            }
        }
    }
}

答案 5 :(得分:0)

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