简体   繁体   中英

Android - tablayout with custom view tabs - drawable selector cannot be applied

I am trying to set up custom tabs in a tablayout using compile 'com.android.support:design:25.3.1' in gradle.

I want to use selectors so that when a tab is clicked it changes based on its state.

So I've tried the following unsuccessfully :

this is my activity xml:

<ViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:background="@color/white"/>

<android.support.design.widget.TabLayout
    android:id="@+id/tabLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:tabMode="fixed"
    app:tabGravity="fill"
    style="@style/MyCustomTabLayout"
    />

here is the style i use for the tabLayout:

<style name="MyCustomTabLayout" parent="Widget.Design.TabLayout">
       <item name="tabIndicatorColor">@android:color/transparent</item>
   </style>

which hides the underline.

here is one of my selectors for my home tab:

here is the custom view i have for each tab:

<ImageView
    android:id="@+id/iv_imgview"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    tools:src="@drawable/home_tab_selector"

    />

<TextView
    android:id="@+id/tv_tab_name"
    android:layout_gravity="center"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    tools:text="HOME"
    />

and here is the portion of code that creates the tablayout:

for (int i = 0; i < NUM_OF_TABS; i++)
           tabLayout.addTab(tabLayout.newTab());

       adapter = new LandingPagerAdapter(getApplicationContext(),getSupportFragmentManager(), tabLayout.getTabCount());

       //Adding adapter to pager
       viewPager.setAdapter(adapter);

       tabLayout.addOnTabSelectedListener(this);
       tabLayout.setupWithViewPager(viewPager);

       // Iterate over all tabs and set the custom view
       for (int i = 0; i < tabLayout.getTabCount(); i++) {
           TabLayout.Tab tab = tabLayout.getTabAt(i);
           tab.setCustomView(adapter.getTabView(i));
       }

       tabLayout.getTabAt(0).select();

and finally here is the getTabView method responsible for applying the selector and custom view:

public class LandingPagerAdapter extends FragmentStatePagerAdapter {

    private final Context context;
    //integer to count number of tabs
    int tabCount;
    private Fragment mCurrentFragment;

    private String[] tabTitles = new String[]{"Home", "tab2"};

    // configure tab icons
    int[] imageTabResId = {
            R.drawable.home_tab_selector,
            R.drawable.tab_two_selector,;

    //Constructor to the class
    public LandingPagerAdapter(Context context, FragmentManager fm, int tabCount) {
        super(fm);
        this.context = context;
        this.tabCount = tabCount;
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                TabHomeContainerFragment tab1 = new TabHomeContainerFragment();
                return tab1;
            case 1:
                TabTwoContainerFragment tab2 = new TabTwoContainerFragment();; //Todo: these should all be containers
                return tab2;
            default:
                return null;
        }
    }

    //Overriden method getCount to get the number of tabs
    @Override
    public int getCount() {
        return tabCount;
    }

    public Fragment getCurrentFragment() {
        return mCurrentFragment;
    }

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

    @Override
    public CharSequence getPageTitle(int position) {
        return tabTitles[position];
    }

    public View getTabView(int position) {
        // Given you have a custom layout in `res/layout/custom_tab.xml` with a TextView and ImageView
        View v = LayoutInflater.from(context).inflate(R.layout.custom_landingpagetab, null);
        TextView tv = (TextView) v.findViewById(R.id.tv_tab_name);
        tv.setText(tabTitles[position]);
        ImageView img = (ImageView) v.findViewById(R.id.iv_imgview);
        img.setImageDrawable(ContextCompat.getDrawable(getApplicationContext(),imageTabResId[position]));
        return v;
    }

}

Notice in getTabView i am setting the image resource to be the selector in the array in the class field. but nothing happens on the device on api 24 i have been testing on.

I'm using support library 27.1.1 and facing the same problem. After some research I found that the state_selected must be defined clearly. See code below:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_chat_disabled" android:state_selected="false"/>
    <item android:drawable="@drawable/ic_chat_enabled" android:state_selected="true"/>
</selector>

android:state_selected="false" is must have!

i ended up dropping the selector approach and just getting my customView from the tab. then i can change its view elements. i had a set of images in an array for selected and another for unselected.

then when the tabs switched i switch between the images based on tab position:

@Override
    public void onTabSelected(TabLayout.Tab tab) {
        viewPager.setCurrentItem(tab.getPosition());
        ImageView iv = (ImageView) tab.getCustomView().findViewById(R.id.iv_imgview);
        TextView tv = (TextView) tab.getCustomView().findViewById(R.id.tv_tab_name);

        iv.setImageDrawable(ContextCompat.getDrawable(this, imageTabResId_selected[tab.getPosition()]));
        tv.setTextColor(ContextCompat.getColor(this, R.color.black));

    }
@Override
public void onTabUnselected(TabLayout.Tab tab) {
    ImageView iv = (ImageView) tab.getCustomView().findViewById(R.id.iv_imgview);
    TextView tv = (TextView) tab.getCustomView().findViewById(R.id.tv_tab_name);

    iv.setImageDrawable(ContextCompat.getDrawable(this, imageTabResId[tab.getPosition()]));
    tv.setTextColor(ContextCompat.getColor(this, R.color.tabs_default_text));

}

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

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM