Android - 带有自定义视图选项卡的表格布局 - 无法应用可绘制选择器

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

我正在尝试使用 gradle 中的编译 'com.android.support:design:25.3.1' 在 tablayout 中设置自定义选项卡。

我想使用选择器,以便在单击选项卡时它会根据其状态发生变化。

所以我尝试了以下方法但没有成功:

这是我的 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"
    />

这是我用于 tabLayout 的样式:

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

隐藏下划线。

这是我的主页选项卡选择器之一:

这是我为每个选项卡设置的自定义视图:

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

这里是创建表格布局的代码部分:

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();

最后是负责应用选择器和自定义视图的 getTabView 方法:

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;
    }

}

在 getTabView 中注意,我将图像资源设置为 class 字段中数组中的选择器。 但是我一直在测试的 api 24 设备上没有任何反应。

我最终放弃了选择器方法,只是从选项卡中获取我的 customView。然后我可以改变它的视图元素。我在数组中有一组图像用于选择,另一组用于未选择。

然后当标签切换时,我根据标签位置在图像之间切换:

@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) {

}

我正在使用支持库 27.1.1 并面临同样的问题。经过一些研究,我发现 state_selected 必须明确定义。请参阅下面的代码:

<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"必须有!