Селектор вкладок не работает на предыдущей вкладке, щелкая при прокрутке на viewpager

Я следую этому примеру..

У меня одна проблема, когда я нажимаю ViewPager соответствующий fragment, но когда я прокручиваю слева направо или справа налево и выбираю предыдущую вкладку, появляется индикатор Tab на новой выбранной вкладке, но соответствующие fragment не отображаются на ViewPager. Пожалуйста, помогите мне, где я ошибаюсь?

Ответ 1

Это была ошибка в поддержке lib 23.0.0, но она решена в 23.0.1. Прежде всего, обновите свою справочную библиотеку с помощью менеджера SDK из раздела "Дополнительные". и напишите следующую строку в файле 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

Ответ 2

В вашей деятельности после поиска Views по идентификатору вы должны "настроить" свои ViewPager и TabLayout. Некоторые необходимые функции могут быть: " addOnPageChangeListener" для ViewPager и " setOnTabSelectedListener" для вашего 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

Ответ 3

Это то, что я использую и прекрасно работаю.

Adapter:

    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, поэтому они также хранятся в памяти.

Ответ 4

Ни один из вышеперечисленных ответов не работал у меня. AS конца 2016 ошибка в библиотеке поддержки дизайна 24 +. Я смог исправить эту проблему, обернув макет вкладки внутри компоновка координатора

Ответ 5

У меня есть более короткий вариант, чтобы исправить эту ошибку (поддержка поддержки Android 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();
            }
        }
    }
}

Ответ 6

Используете ли вы библиотеку поддержки версии 23.0.0. Возникла проблема https://code.google.com/p/android/issues/detail?id=183123, которая похожа на вашу. Если это так, обновите версию своей поддержки до 23.0.1. Эта проблема исправлена.