Android TabLayout Дизайн Android

Я пытаюсь заставить работать новый TabLayout в библиотеке дизайна Android.

Я слежу за этим постом:

http://android-developers.blogspot.com/2015/05/android-design-support-library.html

и документация:

http://developer.android.com/reference/android/support/design/widget/TabLayout.html

И придумал следующий код в моей деятельности, но вкладка не отображается, когда я запускаю активность.

Я попытался добавить в файл макета активности, но он говорит, что не может найти этот тег xml.

public class TabActivity extends BaseActivity {

    SectionPagerAdapter mSectionsPagerAdapter;
    ViewPager mViewPager;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_tab);

        LinearLayout v = (LinearLayout)findViewById(R.id.tabContainer);

        TabLayout tabLayout = new TabLayout(this);
        tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
        tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
        tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));

        tabLayout.setLayoutParams(new LinearLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, 50));

        v.addView(tabLayout);

        mSectionsPagerAdapter = new SectionPagerAdapter(getFragmentManager());

        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        tabLayout.setupWithViewPager(mViewPager);
        mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));

    }

    public class SectionPagerAdapter extends FragmentPagerAdapter {

        private String TAG = "SectionPagerAdapter";

        public SectionPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position)
        {
            return new Fragment();
        }

        @Override
        public int getCount() {
            return 2;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            Locale l = Locale.getDefault();
            switch (position) {
                case 0:
                    return "test";
                case 1:
                    return "test";
                case 2:
            }
            return null;
        }
    }
}

В мой файл gradle добавлено следующее

 compile 'com.android.support:design:22.2.0'

person TWilly    schedule 29.05.2015    source источник
comment
Я нашел эту хорошую статью. /codepath/android_guides/wiki/   -  person TWilly    schedule 01.06.2015
comment
Я только что опубликовал учебник по ViewPager с вкладками, в котором есть отдельная обратная навигация для каждой вкладки. Это может быть интересно и вам: medium.com/@nilan/   -  person marktani    schedule 03.01.2016


Ответы (6)


Мне только что удалось настроить новый TabLayout, поэтому вот быстрые шаги для этого (ノ◕ヮ◕)ノ*:・゚✧

  1. Добавьте зависимости в файл build.gradle:

    dependencies {
        compile 'com.android.support:design:23.1.1'
    }
    
  2. Добавьте TabLayout внутри вашего макета

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical">
    
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"/>
    
        <android.support.design.widget.TabLayout
            android:id="@+id/tab_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    
        <android.support.v4.view.ViewPager
            android:id="@+id/pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    
    </LinearLayout>
    
  3. Настройте свою активность следующим образом:

    import android.os.Bundle;
    import android.support.design.widget.TabLayout;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentPagerAdapter;
    import android.support.v4.view.ViewPager;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.Toolbar;
    
    public class TabLayoutActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_pull_to_refresh);
    
            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
            TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
            ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
    
            if (toolbar != null) {
                setSupportActionBar(toolbar);
            }
    
            viewPager.setAdapter(new SectionPagerAdapter(getSupportFragmentManager()));
            tabLayout.setupWithViewPager(viewPager);
        }
    
        public class SectionPagerAdapter extends FragmentPagerAdapter {
    
            public SectionPagerAdapter(FragmentManager fm) {
                super(fm);
            }
    
            @Override
            public Fragment getItem(int position) {
                switch (position) {
                    case 0:
                        return new FirstTabFragment();
                    case 1:
                    default:
                        return new SecondTabFragment();
                }
            }
    
            @Override
            public int getCount() {
                return 2;
            }
    
            @Override
            public CharSequence getPageTitle(int position) {
                switch (position) {
                    case 0:
                        return "First Tab";
                    case 1:
                    default:
                        return "Second Tab";
                }
            }
        }
    
    }
    
person Oleksii Shliama    schedule 30.05.2015
comment
выглядит неплохо! требуется компиляция «com.android.support:recyclerview-v7:22.2.0»? Я думаю, что я просто пропустил добавление его в свой макет. - person TWilly; 01.06.2015
comment
@TWilly нет, поддержка: recyclerview не требуется. Я удалил это из ответа. - person Oleksii Shliama; 01.06.2015
comment
Как добавить пользовательские шрифты в TabLayout?? - person DroidLearner; 04.06.2015
comment
@DroidLearner, если вы хотите настроить свои вкладки больше, чем изменение цвета текста или значка, вы можете использовать метод setCustomView() при добавлении своих вкладок в виджет TabLayout. developer.android .com/reference/android/support/design/widget/ - person Oleksii Shliama; 04.06.2015
comment
Я использую ту же настройку, все хорошо, когда я прокручиваю страницы, вкладка всегда обновляется. но когда я выбираю вкладку, фрагмент не всегда обновляется. В 30% случаев он остается на той же странице. Я делаю что-то неправильно? Или это баг, так как он новый. - person jasxir; 24.06.2015
comment
@jasxir Я не могу воспроизвести вашу проблему с той же настройкой, которая описана в моем ответе. Кроме того, я использую это в производстве, и я еще не получил никаких отчетов об ошибках в поведении вкладок. Итак, перепроверьте свой код, и если проблема все еще существует, мне нужно будет увидеть ее (фрагмент образца, где ее можно воспроизвести), чтобы помочь вам. - person Oleksii Shliama; 24.06.2015
comment
Теперь я заменил tabLayout.setupWithViewPager(viewPager); на три вещи, которые должен делать этот метод: добавление OnTabSelectListener к TabLayout, заполнение вкладок из PagerAdapter и добавление addOnPageChangeListener к ViewPager. Так что теперь он работает нормально. Но, как упоминалось в документе API tabLayout.setupWithViewPager(viewPager);, он делает эти 3 вещи, когда я делаю их сам, все работает нормально, но с этой одной строкой это кажется ненадежным. - person jasxir; 25.06.2015
comment
Я воспроизвожу это, перелистывая на другую страницу, 2 из 2 в моем случае. Затем щелкните вкладку, чтобы вернуться на страницу 1. В большинстве случаев индикатор табуляции скользит, но страница остается прежней. - person jasxir; 25.06.2015
comment
@jasxir хорошо, метод setupWithViewPager() делает эти 3 вещи (вы можете проверить исходный код), поэтому я действительно считаю, что вы где-то ошиблись. Тем не менее, я не уверен на 100%, что это не ошибка Android, потому что... ну, ошибок полно. - person Oleksii Shliama; 25.06.2015
comment
Спасибо за ваш пример! Это действительно хорошо. Однако у меня возникает вопрос: зачем нам панель инструментов? Это обязательно или необязательно? :) - person Triet Doan; 15.08.2015
comment
@Forte_201092 Forte_201092 ну, это абсолютно необязательно, мне это просто нужно для моего приложения :) - person Oleksii Shliama; 19.08.2015
comment
Благодаря компиляции «com.android.support:design:23.1.1» проблема решена. - person Sam; 24.07.2016

Мне пришлось собирать информацию из разных источников, чтобы собрать работающий TabLayout. Ниже представлен полный вариант использования, который можно изменить по мере необходимости.

Убедитесь, что файл модуля build.gradle содержит зависимость от com.android.support:design.

dependencies {
    compile 'com.android.support:design:23.1.1'
}

В моем случае я создаю действие About в приложении с помощью TabLayout. Я добавил следующий раздел в AndroidMainifest.xml. Установка parentActivityName позволяет домашней стрелке вернуть пользователя к основному действию.

<!-- android:configChanges="orientation|screenSize" makes the activity not reload when the orientation changes. -->
<activity
    android:name=".AboutActivity"
    android:label="@string/about_app"
    android:theme="@style/MyApp.About"
    android:parentActivityName=".MainActivity"
    android:configChanges="orientation|screenSize" >

    <!-- android.support.PARENT_ACTIVITY is necessary for API <= 15. -->
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value=".MainActivity" />
</activity>

styles.xml содержит следующие записи. Это приложение имеет белую панель приложений для основного действия и синюю панель приложения для действия «О программе». Нам нужно установить colorPrimaryDark для активности About, чтобы строка состояния над AppBar была синей.

<style name="MyApp" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorAccent">@color/blue</item>
</style>

<style name="MyApp.About" />

<!-- ThemeOverlay.AppCompat.Dark.ActionBar" makes the text and the icons in the AppBar white. -->
<style name="MyApp.DarkAppBar" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />

<style name="MyApp.AppBarOverlay" parent="ThemeOverlay.AppCompat.ActionBar" />

<style name="MyApp.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />

Также есть styles.xml (v19). Он находится по адресу src/main/res/values-v19/styles.xml. Этот файл применяется только в том случае, если API устройства >= 19.

<!-- android:windowTranslucentStatus requires API >= 19.  It makes the system status bar transparent.
  When it is specified the root layout should include android:fitsSystemWindows="true".
  colorPrimaryDark goes behind the status bar, which is then darkened by the overlay. -->
<style name="MyApp.About">
    <item name="android:windowTranslucentStatus">true</item>
    <item name="colorPrimaryDark">@color/blue</item>
</style>

AboutActivity.java содержит следующий код. В моем случае у меня есть фиксированное количество вкладок (7), поэтому я могу удалить весь код, связанный с динамическими вкладками.

import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;

public class AboutActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.about_coordinatorlayout);

        // We need to use the SupportActionBar from android.support.v7.app.ActionBar until the minimum API is >= 21.
        Toolbar supportAppBar = (Toolbar) findViewById(R.id.about_toolbar);
        setSupportActionBar(supportAppBar);

        // Display the home arrow on supportAppBar.
        final ActionBar appBar = getSupportActionBar();
        assert appBar != null;// This assert removes the incorrect warning in Android Studio on the following line that appBar might be null.
        appBar.setDisplayHomeAsUpEnabled(true);

        //  Setup the ViewPager.
        ViewPager aboutViewPager = (ViewPager) findViewById(R.id.about_viewpager);
        assert aboutViewPager != null; // This assert removes the incorrect warning in Android Studio on the following line that aboutViewPager might be null.
        aboutViewPager.setAdapter(new aboutPagerAdapter(getSupportFragmentManager()));

        // Setup the TabLayout and connect it to the ViewPager.
        TabLayout aboutTabLayout = (TabLayout) findViewById(R.id.about_tablayout);
        assert aboutTabLayout != null; // This assert removes the incorrect warning in Android Studio on the following line that aboutTabLayout might be null.
        aboutTabLayout.setupWithViewPager(aboutViewPager);
    }

    public class aboutPagerAdapter extends FragmentPagerAdapter {
        public aboutPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        // Get the count of the number of tabs.
        public int getCount() {
            return 7;
        }

        @Override
        // Get the name of each tab.  Tab numbers start at 0.
        public CharSequence getPageTitle(int tab) {
            switch (tab) {
                case 0:
                    return getString(R.string.version);

                case 1:
                    return getString(R.string.permissions);

                case 2:
                    return getString(R.string.privacy_policy);

                case 3:
                    return getString(R.string.changelog);

                case 4:
                    return getString(R.string.license);

                case 5:
                    return getString(R.string.contributors);

                case 6:
                    return getString(R.string.links);

                default:
                    return "";
            }
        }

        @Override
        // Setup each tab.
        public Fragment getItem(int tab) {
            return AboutTabFragment.createTab(tab);
        }
    }
}

AboutTabFragment.java используется для заполнения каждой вкладки. В моем случае первая вкладка имеет LinearLayout внутри ScrollView, а все остальные имеют WebView в качестве корневого макета.

import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.TextView;

public class AboutTabFragment extends Fragment {
    private int tabNumber;

    // AboutTabFragment.createTab stores the tab number in the bundle arguments so it can be referenced from onCreate().
    public static AboutTabFragment createTab(int tab) {
        Bundle thisTabArguments = new Bundle();
        thisTabArguments.putInt("Tab", tab);
        AboutTabFragment thisTab = new AboutTabFragment();
        thisTab.setArguments(thisTabArguments);
        return thisTab;
    }

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

        // Store the tab number in tabNumber.
        tabNumber = getArguments().getInt("Tab");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View tabLayout;

        // Load the about tab layout.  Tab numbers start at 0.
        if (tabNumber == 0) {
            // Setting false at the end of inflater.inflate does not attach the inflated layout as a child of container.
            // The fragment will take care of attaching the root automatically.
            tabLayout = inflater.inflate(R.layout.about_tab_version, container, false);
        } else { // load a WebView for all the other tabs.  Tab numbers start at 0.
            // Setting false at the end of inflater.inflate does not attach the inflated layout as a child of container.
            // The fragment will take care of attaching the root automatically.
            tabLayout = inflater.inflate(R.layout.about_tab_webview, container, false);
            WebView tabWebView = (WebView) tabLayout;

            switch (tabNumber) {
                case 1:
                tabWebView.loadUrl("file:///android_asset/about_permissions.html");
                    break;

                case 2:
                    tabWebView.loadUrl("file:///android_asset/about_privacy_policy.html");
                    break;

                case 3:
                    tabWebView.loadUrl("file:///android_asset/about_changelog.html");
                    break;

                case 4:
                    tabWebView.loadUrl("file:///android_asset/about_license.html");
                    break;

                case 5:
                    tabWebView.loadUrl("file:///android_asset/about_contributors.html");
                    break;

                case 6:
                    tabWebView.loadUrl("file:///android_asset/about_links.html");
                    break;

                default:
                    break;
            }
        }

        return tabLayout;
    }
}

about_coordinatorlayout.xml выглядит следующим образом:

<!-- android:fitsSystemWindows="true" moves the AppBar below the status bar.
  When it is specified the theme should include <item name="android:windowTranslucentStatus">true</item>
  to make the status bar a transparent, darkened overlay. -->
<android.support.design.widget.CoordinatorLayout
    android:id="@+id/about_coordinatorlayout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:fitsSystemWindows="true" >

    <!-- the LinearLayout with orientation="vertical" moves the ViewPager below the AppBarLayout. -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <!-- We need to set android:background="@color/blue" here or any space to the right of the TabLayout on large devices will be white. -->
        <android.support.design.widget.AppBarLayout
            android:id="@+id/about_appbarlayout"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:background="@color/blue"
            android:theme="@style/MyApp.AppBarOverlay" >

            <!-- android:theme="@style/PrivacyBrowser.DarkAppBar" makes the text and icons in the AppBar white. -->
            <android.support.v7.widget.Toolbar
                android:id="@+id/about_toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/blue"
                android:theme="@style/MyApp.DarkAppBar"
                app:popupTheme="@style/MyApp.PopupOverlay" />

            <android.support.design.widget.TabLayout
                android:id="@+id/about_tablayout"
                xmlns:android.support.design="http://schemas.android.com/apk/res-auto"
                android:layout_height="wrap_content"
                android:layout_width="match_parent"
                android.support.design:tabBackground="@color/blue"
                android.support.design:tabTextColor="@color/light_blue"
                android.support.design:tabSelectedTextColor="@color/white"
                android.support.design:tabIndicatorColor="@color/white"
                android.support.design:tabMode="scrollable" />
        </android.support.design.widget.AppBarLayout>

        <!-- android:layout_weight="1" makes about_viewpager fill the rest of the screen. -->
        <android.support.v4.view.ViewPager
            android:id="@+id/about_viewpager"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />
    </LinearLayout>
</android.support.design.widget.CoordinatorLayout>

about_tab_version.xml выглядит следующим образом:

<!-- The ScrollView allows the LinearLayout to scroll if it exceeds the height of the page. -->
<ScrollView
    android:id="@+id/about_version_scrollview"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="wrap_content"
    android:layout_width="match_parent" >

    <LinearLayout
        android:id="@+id/about_version_linearlayout"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:padding="16dp" >

        <!-- Include whatever content you want in this tab here. -->

    </LinearLayout>
</ScrollView>

И about_tab_webview.xml:

<!-- This WebView displays inside of the tabs in AboutActivity. -->
<WebView
    android:id="@+id/about_tab_webview"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Есть также записи в strings.xml

<string name="about_app">About App</string>
<string name="version">Version</string>
<string name="permissions">Permissions</string>
<string name="privacy_policy">Privacy Policy</string>
<string name="changelog">Changelog</string>
<string name="license">License</string>
<string name="contributors">Contributors</string>
<string name="links">Links</string>

И colors.xml

<color name="blue">#FF1976D2</color>
<color name="light_blue">#FFBBDEFB</color>
<color name="white">#FFFFFFFF</color>

src/main/assets содержит файлы HTML, указанные в AboutTabFragemnt.java.

person Soren Stoutner    schedule 14.06.2016
comment
откуда у вас метод getString? - person RichArt; 01.02.2017
comment
@RichArt getString — общедоступный метод стандартного контекста Android. developer.android.com/reference/android/content/ В зависимости от того, где вы пишете код, вам может понадобиться использовать getResources.getString(). - person Soren Stoutner; 25.03.2017

У меня возникла проблема с изменением меню при изменении фрагмента в ViewPager. В итоге я реализовал код ниже.

Фрагмент информационной панели

public class DashboardFragment extends BaseFragment {

    private Context mContext;
    private TabLayout mTabLayout;
    private ViewPager mViewPager;
    private DashboardPagerAdapter mAdapter;
    private OnModuleChangeListener onModuleChangeListener;
    private NavDashBoardActivity activityInstance;

    public void setOnModuleChangeListener(OnModuleChangeListener onModuleChangeListener) {
        this.onModuleChangeListener = onModuleChangeListener;
    }

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

    //pass -1 if you want to get it via pager
    public Fragment getFragmentFromViewpager(int position) {
        if (position == -1)
            position = mViewPager.getCurrentItem();
        return ((Fragment) (mAdapter.instantiateItem(mViewPager, position)));
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        mContext = getActivity();

        activityInstance = (NavDashBoardActivity) getActivity();

        mTabLayout = (TabLayout) view.findViewById(R.id.tab_layout);
        mViewPager = (ViewPager) view.findViewById(R.id.view_pager);

        final List<EnumUtils.Module> moduleToShow = getModuleToShowList();
        mViewPager.setOffscreenPageLimit(moduleToShow.size());

        for(EnumUtils.Module module :moduleToShow)
            mTabLayout.addTab(mTabLayout.newTab().setText(EnumUtils.Module.getTabText(module)));

        updateTabPagerAndMenu(0 , moduleToShow);

        mAdapter = new DashboardPagerAdapter(getFragmentManager(),moduleToShow);
        mViewPager.setOffscreenPageLimit(mAdapter.getCount());

        mViewPager.setAdapter(mAdapter);

        mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(final TabLayout.Tab tab) {
                    mViewPager.post(new Runnable() {
                    @Override
                    public void run() {
                        mViewPager.setCurrentItem(tab.getPosition());
                    }
                });
            }

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

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

        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                //added to redraw menu on scroll
            }

            @Override
            public void onPageSelected(int position) {
                updateTabPagerAndMenu(position , moduleToShow);
            }

            @Override
            public void onPageScrollStateChanged(int state) {
            }
        });
    }

    //also validate other checks and this method should be in SharedPrefs...
    public static List<EnumUtils.Module> getModuleToShowList(){
        List<EnumUtils.Module> moduleToShow = new ArrayList<>();

        moduleToShow.add(EnumUtils.Module.HOME);
        moduleToShow.add(EnumUtils.Module.ABOUT);

        return moduleToShow;
    }

    public void setCurrentTab(final int position){
        if(mViewPager != null){
            mViewPager.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mViewPager.setCurrentItem(position);
                }
            },100);
        }
    }

    private Fragment getCurrentFragment(){
        return mAdapter.getCurrentFragment();
    }

    private void updateTabPagerAndMenu(int position , List<EnumUtils.Module> moduleToShow){
        //it helps to change menu on scroll
        //http://stackoverflow.com/a/27984263/3496570
        //No effect after changing below statement
        ActivityCompat.invalidateOptionsMenu(getActivity());
        if(mTabLayout != null)
            mTabLayout.getTabAt(position).select();

        if(onModuleChangeListener != null){

            if(activityInstance != null){
                activityInstance.updateStatusBarColor(
                        EnumUtils.Module.getStatusBarColor(moduleToShow.get(position)));
            }
            onModuleChangeListener.onModuleChanged(moduleToShow.get(position));

            mTabLayout.setSelectedTabIndicatorColor(EnumUtils.Module.getModuleColor(moduleToShow.get(position)));
            mTabLayout.setTabTextColors(ContextCompat.getColor(mContext,android.R.color.black)
                    , EnumUtils.Module.getModuleColor(moduleToShow.get(position)));
        }
    }
}

dashboardfragment.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <!-- our tablayout to display tabs  -->
    <android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:tabBackground="@android:color/white"
        app:tabGravity="fill"
        app:tabIndicatorHeight="4dp"
        app:tabMode="scrollable"
        app:tabSelectedTextColor="@android:color/black"
        app:tabTextColor="@android:color/black" />

    <!-- View pager to swipe views -->
    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</LinearLayout>

адаптер DashboardPagerAdapter

public class DashboardPagerAdapter extends FragmentPagerAdapter {

private List<EnumUtils.Module> moduleList;
private Fragment mCurrentFragment = null;

public DashboardPagerAdapter(FragmentManager fm, List<EnumUtils.Module> moduleList){
    super(fm);
    this.moduleList = moduleList;
}

@Override
public Fragment getItem(int position) {
    return EnumUtils.Module.getDashboardFragment(moduleList.get(position));
}

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

@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
    if (getCurrentFragment() != object) {
        mCurrentFragment = ((Fragment) object);
    }
    super.setPrimaryItem(container, position, object);
}

public Fragment getCurrentFragment() {
    return mCurrentFragment;
}

public int getModulePosition(EnumUtils.Module moduleName){
    for(int x = 0 ; x < moduleList.size() ; x++){
        if(moduleList.get(x).equals(moduleName))
            return x;
    }
    return -1;
}

}

И на каждой странице Фрагмента setHasOptionMenu(true) в onCreate и реализовать onCreateOptionMenu. тогда он будет работать правильно.

ДЕАКТИВНОСТЬ

public class NavDashBoardActivity extends BaseActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    private Context mContext;
    private DashboardFragment dashboardFragment;
    private Toolbar mToolbar;
    private DrawerLayout drawer;
    private ActionBarDrawerToggle toggle;

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

        mContext = NavDashBoardActivity.this;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            getWindow().setStatusBarColor(ContextCompat.getColor(mContext,R.color.yellow_action_bar));
        }

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

        updateToolbarText(new ToolbarTextBO("NCompass " ,""));

        drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        toggle = new ActionBarDrawerToggle(
                this, drawer, mToolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.addDrawerListener(toggle);
        toggle.syncState();

        //onclick of back button on Navigation it will popUp fragment...
        toggle.setToolbarNavigationClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(!toggle.isDrawerIndicatorEnabled()) {
                    getSupportFragmentManager().popBackStack();
                }
            }
        });

        final NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setItemIconTintList(null);//It helps to show icon on Navigation
        updateNavigationMenuItem(navigationView);

        navigationView.setNavigationItemSelectedListener(this);

        //Left Drawer Upper Section
        View headerLayout = navigationView.getHeaderView(0); // 0-index header

        TextView userNameTv = (TextView) headerLayout.findViewById(R.id.tv_user_name);
        userNameTv.setText(AuthSharePref.readUserLoggedIn().getFullName());
        RoundedImageView ivUserPic = (RoundedImageView) headerLayout.findViewById(R.id.iv_user_pic);

        ivUserPic.setImageResource(R.drawable.profile_img);

        headerLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //close drawer and add a fragment to it
                drawer.closeDrawers();//also try other methods..
            }
        });

        //ZA code starts...
        dashboardFragment = new DashboardFragment();
        dashboardFragment.setOnModuleChangeListener(new OnModuleChangeListener() {
            @Override
            public void onModuleChanged(EnumUtils.Module module) {
                if(mToolbar != null){
                    mToolbar.setBackgroundColor(EnumUtils.Module.getModuleColor(module));

                    if(EnumUtils.Module.getMenuID(module) != -1)
                        navigationView.getMenu().findItem(EnumUtils.Module.getMenuID(module)).setChecked(true);
                }
            }
        });

        addBaseFragment(dashboardFragment);
        backStackListener();
    }



    public void updateStatusBarColor(int colorResourceID){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            getWindow().setStatusBarColor(colorResourceID);
        }
    }

    private void updateNavigationMenuItem(NavigationView navigationView){
        List<EnumUtils.Module> modules =  DashboardFragment.getModuleToShowList();

        if(!modules.contains(EnumUtils.Module.MyStores)){
            navigationView.getMenu().findItem(R.id.nav_my_store).setVisible(false);
        }
        if(!modules.contains(EnumUtils.Module.Livewall)){
            navigationView.getMenu().findItem(R.id.nav_live_wall).setVisible(false);
        }
    }

    private void backStackListener(){
        getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
            @Override
            public void onBackStackChanged() {

                if(getSupportFragmentManager().getBackStackEntryCount() >= 1)
                {
                    toggle.setDrawerIndicatorEnabled(false); //disable "hamburger to arrow" drawable
                    toggle.setHomeAsUpIndicator(R.drawable.ic_arrow_back_black_24dp); //set your own
                    ///toggle.setDrawerArrowDrawable();
                    ///toggle.setDrawerIndicatorEnabled(false); // this will hide hamburger image
                    ///Toast.makeText(mContext,"Update to Arrow",Toast.LENGTH_SHORT).show();
                }
                else{
                    toggle.setDrawerIndicatorEnabled(true);
                }
                if(getSupportFragmentManager().getBackStackEntryCount() >0){
                    if(getCurrentFragment() instanceof DashboardFragment){
                        Fragment subFragment = ((DashboardFragment) getCurrentFragment())
                                .getViewpager(-1);
                    }
                }
                else{

                }
            }
        });
    }

    private void updateToolBarTitle(String title){
        getSupportActionBar().setTitle(title);
    }
    public void updateToolBarColor(String hexColor){
        if(mToolbar != null)
            mToolbar.setBackgroundColor(Color.parseColor(hexColor));
    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        if (drawer.isDrawerOpen(GravityCompat.START))
            getMenuInflater().inflate(R.menu.empty, menu);

        return super.onCreateOptionsMenu(menu);//true is wriiten first..
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == android.R.id.home)
        {
            if (drawer.isDrawerOpen(GravityCompat.START))
                drawer.closeDrawer(GravityCompat.START);
            else {
                if (getSupportFragmentManager().getBackStackEntryCount() > 0) {

                } else
                    drawer.openDrawer(GravityCompat.START);
            }

            return false;///true;
        }

        return false;// false so that fragment can also handle the menu event. Otherwise it is handled their
        ///return super.onOptionsItemSelected(item);
    }

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();

        if (id == R.id.nav_my_store) {
            // Handle the camera action
            dashboardFragment.setCurrentTab(EnumUtils.Module.MyStores);
        } 
        }else if  (id == R.id.nav_log_out)  {
            Dialogs.logOut(mContext);
        }

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }


    public void updateToolbarText(ToolbarTextBO toolbarTextBO){
        mToolbar.setTitle("");
        mToolbar.setSubtitle("");
        if(toolbarTextBO.getTitle() != null && !toolbarTextBO.getTitle().isEmpty())
            mToolbar.setTitle(toolbarTextBO.getTitle());
        if(toolbarTextBO.getDescription() != null && !toolbarTextBO.getDescription().isEmpty())
            mToolbar.setSubtitle(toolbarTextBO.getDescription());*/

    }

    @Override
    public void onPostCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
        super.onPostCreate(savedInstanceState, persistentState);
        // Sync the toggle state after onRestoreInstanceState has occurred.
        toggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        toggle.onConfigurationChanged(newConfig);
    }
}
person AndroidGeek    schedule 02.05.2017

Я пытаюсь решить, вот мой код.

сначала добавьте зависимость в build.gradle (приложение).

dependencies {
    compile 'com.android.support:design:23.1.1'
}

Создайте PagerAdapter.class

public class PagerAdapter extends FragmentPagerAdapter {

    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

    public PagerAdapter(FragmentManager manager) {
        super(manager);
    }

    @Override
    public Fragment getItem(int position) {
        Log.i("PosTabItem",""+position);
        return mFragmentList.get(position);
    }

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

    public void addFragment(Fragment fragment, String title) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        Log.i("PosTab",""+position);

        return mFragmentTitleList.get(position);
    }
}

создать файл activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:background="?attr/colorPrimary"
        android:elevation="6dp"
        android:minHeight="?attr/actionBarSize"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

    <android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/toolbar"
        android:background="?attr/colorPrimary"
        android:elevation="6dp"
        android:minHeight="?attr/actionBarSize"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />

    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="fill_parent"
        android:layout_below="@id/tab_layout" />

</RelativeLayout>

создайте MainActivity.class

public class MainActivity extends AppCompatActivity {

    Pager pager;
    @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);


        final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
         pager = new Pager(getSupportFragmentManager());

        pager.addFragment(new FragmentOne(), "One");

        viewPager.setAdapter(pager);

        tabLayout.setupWithViewPager(viewPager);
        tabLayout.setTabMode(TabLayout.MODE_FIXED);
        tabLayout.setSmoothScrollingEnabled(true);

        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));

        tabLayout.setOnTabSelectedListener(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

ящик фрагмент_one.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:text="Location"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

Создайте FragmentOne.class

public class FragmentOne extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_one, container,false);
        return view;
    }
}
person Firdosh    schedule 15.11.2017

Итак, простой способ:

XML:

<android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#fff"/>
<android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

Java-код:

private ViewPager viewPager;

private String[] PAGE_TITLES = new String[]{
        "text1",
        "text1",
        "text3"
};
private final Fragment[] PAGES = new Fragment[]{
        new fragment1(), 
        new fragment2(),
        new fragment3()

};

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

    /**TODO ***************tebLayout*************************/
    viewPager = findViewById(R.id.viewpager);
    viewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
    TabLayout tabLayout = findViewById(R.id.tab_layout);
    tabLayout.setSelectedTabIndicatorColor(Color.parseColor("#1f57ff"));
    tabLayout.setSelectedTabIndicatorHeight((int) (4 * 
    getResources().getDisplayMetrics().density));
    tabLayout.setTabTextColors(Color.parseColor("#9d9d9d"), 
    Color.parseColor("#0d0e10"));
    tabLayout.setupWithViewPager(viewPager);
    /***************************************************************************/
    }
person Eng.OsamaYousef    schedule 21.03.2019

Добавьте это в модуль build.gradle:

implementation 'com.android.support.constraint:constraint-layout:1.1.3'

implementation 'com.android.support:design:28.0.0'
person Ahmed    schedule 18.08.2019