Изменение цвета фона вкладки в TabLayout (библиотека поддержки дизайна Android) не занимает все пространство вкладки

У меня есть TabLayout (библиотека поддержки дизайна), которая привязана к ViewPager, содержащему три вкладки. Я разработал собственный макет и установил его для каждой вкладки в TabLayout. Я пытался изменить цвет фона текущей выбранной вкладки. Цвет обволакивает только текст на вкладке, но не занимает все пространство вкладки.

Ниже приведены фрагменты кода моей активности и файл пользовательского макета.

Код действия

public class CustomTabLayoutActivity extends AppCompatActivity {

private TabLayout tabLayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_custom_tab_layout);
    tabLayout = (TabLayout) findViewById(R.id.tabLayout);
    ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
    setupViewPager(viewPager);
    tabLayout.setupWithViewPager(viewPager);
    tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
    setupTabLayout();
    viewPager.setCurrentItem(0);
    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            for (int i = 0; i < tabLayout.getTabCount(); i++) {
                if (i == position) {
                    tabLayout.getTabAt(i).getCustomView().setBackgroundColor(Color.parseColor("#198C19"));
                } else {
                    tabLayout.getTabAt(i).getCustomView().setBackgroundColor(Color.parseColor("#f4f4f4"));
                }
            }
        }

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


private void setupViewPager(ViewPager viewPager) {
    CustomViewPagerAdapter pagerAdapter = new CustomViewPagerAdapter(getSupportFragmentManager());
    pagerAdapter.addFragments(new OneFragment(), "ONE");
    pagerAdapter.addFragments(new OneFragment(), "TWO");
    pagerAdapter.addFragments(new OneFragment(), "THREE");
    viewPager.setAdapter(pagerAdapter);
}

private void setupTabLayout() {

    TextView customTab1 = (TextView) LayoutInflater.from(CustomTabLayoutActivity.this)
            .inflate(R.layout.custom_tab_layout, null);
    TextView customTab2 = (TextView) LayoutInflater.from(CustomTabLayoutActivity.this)
            .inflate(R.layout.custom_tab_layout, null);
    TextView customTab3 = (TextView) LayoutInflater.from(CustomTabLayoutActivity.this)
            .inflate(R.layout.custom_tab_layout, null);
    customTab1.setText("ONE");
    tabLayout.getTabAt(0).setCustomView(customTab1);
    customTab2.setText("TWO");
    tabLayout.getTabAt(1).setCustomView(customTab2);
    customTab3.setText("THREE");
    tabLayout.getTabAt(2).setCustomView(customTab3);
}
}

Пользовательский файл макета для каждой вкладки

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@+id/tab"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:layout_gravity="center"
   android:background="#ffffff"
   android:text="Test"
   android:textColor="@android:color/black"
   android:textSize="20sp" />

Вот скриншот вкладок после запуска вышеуказанного кода.

введите описание изображения здесь

Как видите, цвет занимает только текст на вкладке, но не все пространство вкладки. Как этого добиться? Любые идеи/предложения мне очень помогут. Заранее спасибо.


person Itapu Vinay    schedule 16.09.2015    source источник


Ответы (4)


Определите селектор как рисуемый, а также нарисуйте его для выбранных/не выбранных состояний.

Для этого решения я начал с кода из этого ответа, а затем добавил функциональность, которая меняет цвет фона для текущего Таб.

Во-первых, селектор tab_background.xml в папке с возможностью рисования:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/tab_background_selected" android:state_selected="true" />
    <item android:drawable="@drawable/tab_background_unselected" android:state_selected="false" android:state_focused="false" android:state_pressed="false" />
</selector>

Затем tab_background_selected.xml в папке с возможностью рисования:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <solid android:color="#d13fdd1a" />
</shape>

Затем tab_background_unselected.xml в папке с возможностью рисования:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <solid android:color="#3F51B5" />
</shape>

Наконец, в styles.xml укажите используемый селектор, а также укажите стиль индикатора табуляции, поскольку свойство app:tabIndicatorColor в TabLayout теперь будет игнорироваться:

<style name="Base.Widget.Design.TabLayout" parent="android:Widget">
    <item name="tabBackground">@drawable/tab_background</item>
    <item name="tabIndicatorColor">#ff00ff</item>
    <item name="tabIndicatorHeight">2dp</item>
</style>

Результат с примерами цветов выше:

введите описание изображения здесь

введите описание изображения здесь

Дополнительное примечание:

Протестировано с версиями 23.3.0 компонентов библиотеки поддержки:

dependencies {
    compile 'com.android.support:appcompat-v7:23.3.0'
    compile 'com.android.support:cardview-v7:23.3.0'
    compile 'com.android.support:recyclerview-v7:23.3.0'
    compile 'com.android.support:design:23.3.0'
    compile 'com.android.support:support-v4:23.3.0'
}
person Daniel Nugent    schedule 16.09.2015
comment
ВАУ мужик!!! Я пытался добиться этого в течение последних 5 часов. Вы спасли мой день. Это сработало как шарм. - person Itapu Vinay; 16.09.2015
comment
Не могли бы вы объяснить, почему нам нужно добавить несколько строк кода в styles.xml? - person Itapu Vinay; 16.09.2015
comment
Рад, что это сработало для вас! Дополнение к styles.xml предназначено только для того, чтобы связать селектор и чертежи, которые устанавливают цвет фона. - person Daniel Nugent; 16.09.2015
comment
Он отлично работает, когда режим вкладок установлен на фиксированный, но когда установлен на прокручиваемый, расстояние между вкладками теряется. Я использовал tab:padding, чтобы добавить интервал между вкладками. Это правильный подход к этому? - person Itapu Vinay; 18.09.2015
comment
Есть ли способ сделать это так, чтобы выбранная вкладка имела другой цвет в зависимости от позиции вкладки? Например, если первая вкладка зеленая при выборе, а вторая вкладка красная при выборе? Изменить: я думаю, что это можно сделать с помощью OnTabSelectedListener() и использования TabLayout.setBackgroundResource() для каждой вкладки в onTabSelected(). - person OJ7; 02.02.2016
comment
ты бог, ты спаси меня :D - person Evan Ngo; 16.05.2016
comment
Почему state_focused и state_pressed установлены на false, когда они не выбраны, а state_selected установлены только на true, когда они выбраны? - person young_souvlaki; 15.06.2016
comment
это перезаписывает индикатор выбранной вкладки (эта маленькая линия под вкладкой с акцентом).. есть ли способ вернуть его? - person Zuop; 05.07.2016
comment
если кто-то заинтересован в наличии индикатора: stackoverflow.com/ вопросы/38202585/ - person Zuop; 05.07.2016
comment
@zoup извините, я хотел обновить этот ответ навсегда. Спасибо за ссылку. - person Daniel Nugent; 05.07.2016
comment
может быть, старый, но в любом случае, чтобы перестать мерцать при использовании этого с viewPager? - person Tanner Summers; 28.07.2016
comment
@DanielNugent во время свайпа для меня он мерцает между вкладками в течение доли секунды, так как, я думаю, он не знает, на какую вкладку он идет, пока не закончит - person Tanner Summers; 28.07.2016
comment
@tanner да, я листал, когда записывал это - person Daniel Nugent; 28.07.2016
comment
Что делать, если у меня есть несколько tabLayout в моем приложении, и я хочу применить этот эффект к определенному tablayout? - person Zulqurnain Jutt; 01.10.2016
comment
идеальный ответ. но мне очень нравится тот эффект ряби, который сейчас исчез :( - person Milad Faridnia; 16.01.2017
comment
Аналогичный обходной путь можно сделать с элементом Navigation Drawer? я пробовал много неудачных попыток иметь цвет фона Выбранный элемент ящика. - person Veer3383; 01.02.2017
comment
Как это сделать программно - person Sujay U N; 19.02.2017
comment
Поправьте меня если я ошибаюсь. Мы должны добавить следующую строку в TabLayout в xml: style="@style/Base.Widget.Design.TabLayout" Это может быть то, что нужно сделать и @Zulqurnain. - person ColinWa; 22.02.2017
comment
этот код подходит для макета вкладок по умолчанию, но если вы используете настраиваемый вид для макета вкладок, то приведенный выше код не является плодотворным. - person Erum; 23.08.2017
comment
@Erum У меня работает собственный макет для каждой вкладки. На самом деле скриншоты в ответе сделаны из пользовательского макета. Взгляните на реализацию, которую я использовал: stackoverflow.com/a/34581086/4409409 - person Daniel Nugent; 23.08.2017

вы должны использовать:

app:tabBackground="@drawable/tab_selector"
android:background="@color/colorNormal"

tab_selector.xml (в папке Drawable):

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:drawable="@color/colorSelected"/>
    <item android:state_selected="false" android:drawable="@color/colorNormal"/>
</selector>
person Milad jalali    schedule 05.08.2018

Вкладки с эффектом пульсации: В дополнение к ответу Дэниела Ньюджента. Было бы прекрасно добавить эффект пульсации на вкладки. Для этого вы должны добавить эти два чертежа в папку drawable-v21:

tab_background_selected.xml :

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="#63D25B"> <!-- ripple color -->
    <item android:drawable="#d13fdd1a" /> <!-- normal color -->
</ripple>

tab_background_unselected.xml :

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="#606FC7"> <!-- ripple color -->
    <item android:drawable="#3F51B5" /> <!-- normal color -->
</ripple>
person Milad Faridnia    schedule 16.01.2017
comment
Спасибо за это, но я уже получаю волновой эффект с ответом Дэниела Ньюджента. Я использую версию 28.0.0-alpha3 библиотек поддержки - может быть поэтому? - person ban-geoengineering; 14.07.2018
comment
@ban-geoengineering Спасибо за ваш комментарий. Я не видел волнового эффекта с ответом Дэниела в то время, когда писал этот ответ. - person Milad Faridnia; 16.07.2018

Я знаю, что уже довольно поздно отвечать на этот вопрос, но у меня есть другой и простой ответ без создания нового фона или селектора. Tab-Layout имеет заполнение по умолчанию 12dp в начале и конце. Просто установите

app:tabPaddingStart="0dp"
app:tabPaddingEnd="0dp"

чтобы заполнить цвет на вкладке.

person Ashish John    schedule 04.01.2018