Android 如何自定义单个选项卡?(更改背景颜色、指示器颜色和文本颜色)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21335267/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 04:23:38  来源:igfitidea点击:

How to customize individual tabs? (changing background color, indicator color and text color)

androidandroid-viewpagerandroid-tabsandroid-actionbar-compat

提问by Shishi

In this link : How do I apply a style programmatically?

在此链接中:如何以编程方式应用样式?

Kevin Grant gave a explaination to this question my problem with his code is the context part. To be precise :

凯文格兰特解释了这个问题我的代码问题是上下文部分。准确地说:

ctv = new CustomView(context, R.attr.tabStyleAttr);

In this code it says : context cannot be resolved to a variable

在这段代码中,它说:上下文无法解析为变量

I want to apply specific style to tabs and that's why setting theme doesn't work for me. Any alternative to my problem is welcome too of course.

我想将特定样式应用于选项卡,这就是设置主题对我不起作用的原因。当然,也欢迎我的问题的任何替代方案。

I try to change the background color, indicator color and text color of actionbar tabs.

我尝试更改操作栏选项卡的背景颜色、指示器颜色和文本颜色。

@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) 
{
    CustomView ctv;
    ctv = new CustomView(this, R.attr.tabStyleAttr);        
    tab.setCustomView(ctv);  
    mViewPager.setCurrentItem(tab.getPosition());
}

styles.xml

样式文件

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="Theme.Ab" parent="@android:style/Theme.Holo.Light">
        <item name="android:actionBarStyle">@style/abStyle</item> 
        <item name="@attr/actionBarTabStyle">@style/tabStyle</item>        
        <item name="android:actionBarTabTextStyle">@style/tabTextColor</item>
    </style>   

    <style name="abStyle" parent="@android:style/Widget.Holo.Light.ActionBar.Solid">
        <item name="android:background">@drawable/ab_solid_style</item>
        <item name="android:backgroundStacked">@drawable/ab_stacked_solid_style</item>
        <item name="android:backgroundSplit">@drawable/ab_bottom_solid_style</item>
        <item name="android:height">100dp</item>
    </style>    

    <style name="tabStyle" parent="@android:style/Widget.Holo.Light.ActionBar.TabView">

        <item name="android:background">@drawable/tab_indicator_ab_style</item>
    </style>

    <style name="tabTextColor" parent="@android:style/Widget.Holo.Light.ActionBar.TabText">
        <item name="android:textColor">@android:color/white</item>
    </style>



</resources>

MainActivity.java (onCreate)

MainActivity.java (onCreate)

public void onCreate(Bundle savedInstanceState)
    {       
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Create the adapter that will return a fragment for each of the three primary sections
        // of the app.
        mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getSupportFragmentManager());

        // Set up the action bar.
        final ActionBar actionBar = getActionBar();
        //set custom actionbar
        actionBar.setCustomView(R.layout.titlebar);
        //Displays the custom design in the actionbar
        actionBar.setDisplayShowCustomEnabled(true);
        //Turns the homeIcon a View     
        View homeIcon = findViewById(android.R.id.home);
        //Hides the View (and so the icon)
        ((View)homeIcon.getParent()).setVisibility(View.GONE);

        // Specify that we will be displaying tabs in the action bar.
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        // Set up the ViewPager, attaching the adapter and setting up a listener for when the
        // user swipes between sections.
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mAppSectionsPagerAdapter);

        mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener()
        {           
            @Override
            public void onPageSelected(int position)
            {
                    // When swiping between different app sections, select the corresponding tab.
                    // We can also use ActionBar.Tab#select() to do this if we have a reference to the Tab.
                    actionBar.setSelectedNavigationItem(position);
            }
        });

        // For each of the sections in the app, add a tab to the action bar.
        for (int i = 0; i < mAppSectionsPagerAdapter.getCount(); i++)
        {

            // Create a tab with text corresponding to the page title defined by the adapter.
            // Also specify this Activity object, which implements the TabListener interface, as the
            // listener for when this tab is selected.
            Tab tab = actionBar.newTab().setText(mAppSectionsPagerAdapter.getPageTitle(i)).setTabListener(this);            
            actionBar.addTab(tab);
        }
    }

This is what I want to make:

这就是我想做的:

Example

例子



As for the new result using Views this happened

至于使用视图的新结果,这发生了

Using views

使用视图

MainActivity.java

主活动.java

package com.example.android.effectivenavigation;

import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class MainActivity extends FragmentActivity implements ActionBar.TabListener
{
    AppSectionsPagerAdapter mAppSectionsPagerAdapter;
    //The viewpager displays on of the section at a time
    ViewPager mViewPager;

    public void onCreate(Bundle savedInstanceState)
    {       
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Create the adapter that will return a fragment for each of the three primary sections
        // of the app.
        mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getSupportFragmentManager());

        // Set up the action bar.
        final ActionBar actionBar = getActionBar();
        //set custom actionbar
        actionBar.setCustomView(R.layout.titlebar);
        //Displays the custom design in the actionbar
        actionBar.setDisplayShowCustomEnabled(true);
        //Turns the homeIcon a View     
        View homeIcon = findViewById(android.R.id.home);
        //Hides the View (and so the icon)
        ((View)homeIcon.getParent()).setVisibility(View.GONE);


        // Specify that we will be displaying tabs in the action bar.
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        // Set up the ViewPager, attaching the adapter and setting up a listener for when the
        // user swipes between sections.
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mAppSectionsPagerAdapter);

        mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener()
        {           
            @Override
            public void onPageSelected(int position)
            {
                    // When swiping between different app sections, select the corresponding tab.
                    // We can also use ActionBar.Tab#select() to do this if we have a reference to the Tab.
                    actionBar.setSelectedNavigationItem(position);
            }
        });
       /*final Tab firstTab = actionBar.newTab()
                .setText(mAppSectionsPagerAdapter.getPageTitle(0))
                .setTabListener(this)
                .setCustomView(R.id.nieuws_tab_layout);
        /*final Tab secondTab = actionBar.newTab()
                 .setText(mAppSectionsPagerAdapter.getPageTitle(1))
                 .setCustomView(R.id.nieuws_tab_layout);
        final Tab thirdTab = actionBar.newTab()
                .setText(mAppSectionsPagerAdapter.getPageTitle(2))
                .setCustomView(R.id.nieuws_tab_layout);

        actionBar.addTab(firstTab);
        actionBar.addTab(secondTab);
        actionBar.addTab(thirdTab);*/

        // For each of the sections in the app, add a tab to the action bar.
        for (int i = 0; i < mAppSectionsPagerAdapter.getCount(); i++)
        {
            if(i == 0)
            {
                final View firstCustomView = new CustomView(this);
                //firstCustomView.setBackgroundColor(Color.BLUE);
                Tab tab = actionBar.newTab().setText(mAppSectionsPagerAdapter.getPageTitle(i)).setTabListener(this).setCustomView(R.layout.nieuws_tab_layout);
                actionBar.addTab(tab);
            }
            else
            {
            // Create a tab with text corresponding to the page title defined by the adapter.
            // Also specify this Activity object, which implements the TabListener interface, as the
            // listener for when this tab is selected.
            Tab tab = actionBar.newTab().setText(mAppSectionsPagerAdapter.getPageTitle(i)).setTabListener(this);            
            actionBar.addTab(tab);
            }
        }
    }

    @Override
    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) 
    {
    }

    @Override
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) 
    {
        //CustomView ctv;
        //ctv = new CustomView(context, R.attr.tabStyleAttr);
        // When the given tab is selected, switch to the corresponding page in the ViewPager.
        //LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
        //View tabView = inflater.inflate(R.layout.nieuws_tab_layout, null);
        //tabView.setBackgroundColor(0xFF00FF00);
        //tab.setCustomView(tabView);  
        mViewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction)
    {
    }

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

        @Override
        public Fragment getItem(int i) 
        {
            switch (i)
            {
                case 0:
                    // The first section of the app is the most interesting -- it offers
                    // a launchpad into the other demonstrations in this example application.
                    return new LaunchpadSectionFragment();

                default:
                    // The other sections of the app are dummy placeholders.
                    Fragment fragment = new DummySectionFragment();
                    Bundle args = new Bundle();
                    args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, i + 1);
                    fragment.setArguments(args);
                    return fragment;
            }
        }

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

        @Override
        public CharSequence getPageTitle(int position) 
        {
            switch(position)
            {
                case 0:
                {
                    return "Tab1";
                }
                case 1:
                {
                    return "Tab2";
                }
                case 2:
                {
                    return "Tab3";
                }
                default:
                {
                    return "Section " + (position + 1);
                }
            }
        }
    }
    public static class LaunchpadSectionFragment extends Fragment
    {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
        {
            View rootView = inflater.inflate(R.layout.fragment_section_launchpad, container, false);

            // Demonstration of a collection-browsing activity.
            rootView.findViewById(R.id.demo_collection_button).setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View view) 
                {
                    Intent intent = new Intent(getActivity(), CollectionDemoActivity.class);
                    startActivity(intent);
                }
            });

            // Demonstration of navigating to external activities.
            rootView.findViewById(R.id.demo_external_activity).setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View view)
                {
                    // Create an intent that asks the user to pick a photo, but using
                    // FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET, ensures that relaunching
                    // the application from the device home screen does not return
                    // to the external activity.
                    Intent externalActivityIntent = new Intent(Intent.ACTION_PICK);
                    externalActivityIntent.setType("image/*");
                    externalActivityIntent.addFlags(
                    Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
                    startActivity(externalActivityIntent);
                }
            });
            return rootView;
        }
    }

    /**
     * A dummy fragment representing a section of the app, but that simply displays dummy text.
     */
    public static class DummySectionFragment extends Fragment
    {
        public static final String ARG_SECTION_NUMBER = "section_number";

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            View rootView = inflater.inflate(R.layout.fragment_section_dummy, container, false);
            Bundle args = getArguments();
            ((TextView) rootView.findViewById(android.R.id.text1)).setText(getString(R.string.dummy_section_text, args.getInt(ARG_SECTION_NUMBER)));
            return rootView;
        }
    }
    public class CustomView extends View
    {
        public CustomView(Context context)
        {
            super(context, null);
        }
    } 
}

tab_layout.xml

tab_layout.xml

<?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" >

  <TextView
              android:id="@+id/nieuws_tab_layout"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"              
              android:text="@string/nieuws"
              android:gravity="center_vertical"
              android:layout_marginTop="15dp"
              android:textColor="@android:color/white"
              android:textStyle="bold"
              android:background="@android:color/black"
              />
</LinearLayout>

采纳答案by desseim

Just set your custom view at the tab creation time, something like:

只需在选项卡创建时设置自定义视图,例如:

final Tab firstTab = actionBar.newTab()
                              .setText(mAppSectionsPagerAdapter.getPageTitle(0))
                              .setCustomView(R.id.custom_tab_view_red);
final Tab secondTab = actionBar.newTab()
                               .setText(mAppSectionsPagerAdapter.getPageTitle(1))
                               .setCustomView(R.id.custom_tab_view_blue);
// etc

actionBar.addTab(firstTab);
actionBar.addTab(secondTab);
// etc

in inCreate().

inCreate()

You'll also have to define Viewscorresponding to the above ids in your xml layout file (and not styles).

您还必须在 xml 布局文件中定义与上述Views相对应的ids(而不是styles)。

Or, if you want to create the view directly:

或者,如果您想直接创建视图:

final View firstCustomView = new CustomView(this);
firstCustomView.setBackgroundColor(Color.BLUE);  // or with drawable or resource
final Tab firstTab = actionBar.newTab()
                              .setText(mAppSectionsPagerAdapter.getPageTitle(0))
                              .setCustomView(firstCustomView);
actionBar.addTab(firstTab);
// then same for other tabs, just with another color


Leaving the below information for reference:

留下以下信息以供参考:

To define one such view, you need to specify it an Android Context. This is usually the Activitywhere the tabs will be displayed. Supposing that you initialize your tabs in an Activity, simply pass the Activityinstance as a Context:

要定义一个这样的视图,您需要将其指定为 Android Context。这通常是Activity选项卡的显示位置。假设您在 a 中初始化您的选项卡Activity,只需将Activity实例作为 a传递Context

ctv = new CustomView(this, R.attr.tabStyleAttr);

if from inside the Activity, or for example:

如果从内部Activity,或者例如:

ctv = new CustomView(getActivity(), R.attr.tabStyleAttr);

if from inside a Fragment, etc.

如果从内部 aFragment

As for setting a specific style for action bar tabs, no need to go create a custom view programmatically as you're trying to. Read up a little about the action barfirst, then check the examplethey provide. As you can see, you'll be able to specify the tab style in xml:

至于为操作栏选项卡设置特定样式,无需像您尝试那样以编程方式创建自定义视图。首先阅读有关操作栏的一些内容,然后查看他们提供的示例。如您所见,您将能够在 xml 中指定选项卡样式:

In your manifest file, you can apply the theme to your entire app:

<application android:theme="@style/CustomActionBarTheme" ... />

Or to individual activities:

<activity android:theme="@style/CustomActionBarTheme" ... />

在清单文件中,您可以将主题应用于整个应用程序:

<application android:theme="@style/CustomActionBarTheme" ... />

或个人活动:

<activity android:theme="@style/CustomActionBarTheme" ... />

for example.

例如。

For a complete example matching perfectly your use case, see this Android doc article: https://developer.android.com/training/basics/actionbar/styling.html#CustomTabs. Notice the usage of state-lists to achieve the "when selected style".

有关与您的用例完美匹配的完整示例,请参阅此 Android 文档文章:https: //developer.android.com/training/basics/actionbar/styling.html#CustomTabs。请注意使用状态列表来实现“选择时样式”。

回答by Mostafa Anter

if another one using TabLayout as in my case i used this snippet

如果另一个在我的情况下使用 TabLayout 我使用了这个片段

tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            tab.setCustomView(R.layout.chat_tab);

        }

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

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

        }
    });

回答by Tara

I was using Tablayout, which is privided by AndroidStudio library. while adding tabs Just use setCustomView() to each and every tab which you would like to customize. something like below

我使用的是 AndroidStudio 库提供的 Tablayout。添加选项卡时只需将 setCustomView() 用于您想要自定义的每个选项卡。像下面这样的东西

    tabLayout.addTab(tabLayout.newTab().setText("FirstTab"));  // default tab
    tabLayout.addTab(tabLayout.newTab().setText("SecondTab").setCustomView(R.layout.tabview));  // Customized tab

And below is the layout design for particular Tab to fill our requirement, Here I am just makeing the Tab text color Different

下面是特定 Tab 的布局设计来满足我们的要求,这里我只是让 Tab 文本颜色不同

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorPrimaryDark">  <!-- TabLayout default color in my case -->
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Procurement"
    android:textAllCaps="true"
    android:textAppearance="@android:style/TextAppearance.DeviceDefault.Small"
    android:textColor="@color/tab_selection"  <!-- textcolor which ever you like-->
    android:textStyle="bold"/>

</LinearLayout>