如何为 android 中标志性 ViewPager 的选定选项卡设置色调?

How to set tint for selected tab of an iconic ViewPager in android?

我正在实现一个带图标的 viewpager,我实现如下:

public class JobDetailTabbedActivity extends AppCompatActivity {

    private int tabPositionToDisplay=0;
    private String productId="";
    private JobDetailPagerAdapter mJobDetailPagerAdapter;
    private ViewPager mViewPager;
    private TabLayout tabLayout;

    private int[] tabIcons = {
            R.drawable.ic_emoji_objects_light_normal,
            R.drawable.ic_emoji_objects_light,
            R.drawable.ic_cast_disabled_light,
            R.drawable.ic_cast_disabled_light
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_job_detail_tabbed);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        mJobDetailPagerAdapter = new JobDetailPagerAdapter(getSupportFragmentManager());


        mViewPager = (ViewPager) findViewById(R.id.tab_anim_viewpager);
        mViewPager.setAdapter(mJobDetailPagerAdapter);
        mViewPager.setCurrentItem(tabPositionToDisplay);
        tabLayout = (TabLayout) findViewById(R.id.tab_anim_tabs);
        tabLayout.setupWithViewPager(mViewPager);


    }

    public class JobDetailPagerAdapter extends FragmentPagerAdapter {


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

        @Override
        public Fragment getItem(int position) {
            // getItem is called to instantiate the fragment for the given page.
            // Return a PlaceholderFragment (defined as a static inner class below).
            switch (position){
                case 0:
                    return JobDetailInfoFragment.newInstance();
                case 1:
                    return JobDetailServiceFragment.newInstance();
                case 2:
                    return JobDetailChatFragment.newInstance();
                case 3:
                    return JobDetailNotesFragment.newInstance();
                default:
                    return JobDetailInfoFragment.newInstance();
            }
        }

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


        @Override
        public CharSequence getPageTitle(int position) {
            Drawable image = ContextCompat.getDrawable(JobDetailTabbedActivity.this, tabIcons[position]);
            image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());

            SpannableString sb = new SpannableString(" ");
            ImageSpan imageSpan = new ImageSpan(image, ImageSpan.ALIGN_BOTTOM);
            sb.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            return sb;
        }
    }

}

我可以在选项卡上获取图标,但是如何为选项卡的选定图标设置色调颜色?

我在 google 中搜索过,但是 none 如果可用的教程(无论我看到了什么)是关于设置图标色调的,请任何人帮助我。

有几种方法可以实现这一点。

第一种方式

创建一个 selector 文件并在您的 tabIcon 数组中使用它们。此外,每当 viewpager 更改时,将可绘制对象的状态设置为已选中,而其他未选中状态,如

int[] state = new int[] {android.R.attr.state_selected}; drawable.setState(state)

所以它会自动 state_selected 可绘制。

第二种方式

您在选项卡中有图标。每当 viewpager 更改或单击选项卡图标时,您都可以调用 drawable.setColorFilter(Color.YOUR_COLOR, PorterDuff.Mode.MULTIPLY) 也不要忘记为其他可绘制对象调用 drawable.clearColorFilter()

祝你好运

您可以根据需要轻松修改 this 教程。

Result

您可以使用 getTabAt(int index) method available in TabLayout class and update the tab icon using setIcon(int drawable_id) 获取选项卡。代码演示如下。

 tabLayout.getTabAt(tab_index).setIcon(highlighted_icon);

使用ViewPager.OnPageChangeListener or TabLayout.TabLayoutOnPageChangeListener你可以得到选中的标签。

我还没有尝试过,但相信这就足够了。

或者你可以试试我在 SlidingTabLayout 的支持下亲自创建的 TabView。

您可以下载文件here

用法

    Integer[] iconUnselectedResourceArray = {R.drawable.ic_tab_post,
                        R.drawable.ic_tab_like, R.drawable.ic_tab_about
                };

                Integer[] iconSelectedResourceArray = {R.drawable.ic_tabactive_post,
                        R.drawable.ic_tabactive_like, R.drawable.ic_tabactive_about
                };

            final SlidingTabLayoutIcons mSlidingTabLayout = (SlidingTabLayoutIcons) findViewById(R.id.tabs);
            mSlidingTabLayout.setCustomTabView(R.layout.profile_tab_items, R.id.tabtext);
            mSlidingTabLayout.setIconResourceArray(iconUnselectedResourceArray);
            mSlidingTabLayout.setIconSelectedResourceArray(iconSelectedResourceArray);
            mSlidingTabLayout.setDistributeEvenly(true); // To make the Tabs Fixed set this true, This makes the tabs Space Evenly in Available width
            mSlidingTabLayout.setColorStateList(getResources().getColorStateList(R.color.profile_view_tab));
            // Setting Custom Color for the Scroll bar indicator of the Tab View
            mSlidingTabLayout.setCustomTabColor(new SlidingTabLayoutIcons.TabColorIcons() {
                @Override
                public int getIndicatorColor(int position) {
                    return getResources().getColor(R.color.base_color);
                }
            });
            mSlidingTabLayout.setViewPager(mViewPager);

XML

  <com.example.SlidingTabLayoutIcons
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/profile_tab_border"
            android:elevation="2dp" />

也看看 this

终于解决了这个问题:

创建自定义小部件:

public class TintableImageView extends ImageView {

    private ColorStateList tint;

    public TintableImageView(Context context) {
        super(context);
    }

    public TintableImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public TintableImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyle) {
        TypedArray a =
                context.obtainStyledAttributes(attrs, R.styleable.TintableImageView, defStyle, 0);
        tint = a.getColorStateList(R.styleable.TintableImageView_tintSelector);
        a.recycle();
    }

    @Override
    protected void drawableStateChanged() {
        super.drawableStateChanged();
        if (tint != null && tint.isStateful()) updateTintColor();
    }

    public void setColorFilter(ColorStateList tint) {
        this.tint = tint;
        super.setColorFilter(tint.getColorForState(getDrawableState(), 0));
    }

    private void updateTintColor() {
        int color = tint.getColorForState(getDrawableState(), 0);
        setColorFilter(color);
    }
}

将此值添加到 attrs.xml:

<declare-styleable name="TintableImageView">
    <attr name="tintSelector" format="reference|color" />
</declare-styleable>

为要在颜色目录中更改的选项卡图像创建一个选择器(在颜色目录中再次重复选择器文件而不是 colors.xml):

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:color="#FFFFFF"
        android:state_pressed="true" />
    <item android:color="#FFFFFF"
        android:state_selected="true" />

    <item android:color="#5F9EA0" />
</selector>

创建一个仅包含自定义小部件的 xml 布局:

<?xml version="1.0" encoding="utf-8"?>
<TintableImageView xmlns:custom="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    custom:tintSelector="@color/selector_tab" />

就是这样,您可以开始了,您必须实现这样的选项卡(仅显示对我发布的代码所做的更改):

public class JobDetailTabbedActivity extends AppCompatActivity {



        private JobDetailPagerAdapter mJobDetailPagerAdapter;
        private ViewPager mViewPager;
        private TabLayout tabLayout;


        @Override
        protected void onCreate(Bundle savedInstanceState) {
            //old code which i have posted
            mJobDetailPagerAdapter = new JobDetailPagerAdapter(getSupportFragmentManager());


            mViewPager = (ViewPager) findViewById(R.id.tab_anim_viewpager);
            mViewPager.setAdapter(mJobDetailPagerAdapter);
            mViewPager.setCurrentItem(tabPositionToDisplay);
            tabLayout = (TabLayout) findViewById(R.id.tab_anim_tabs);
            tabLayout.setupWithViewPager(mViewPager);
            setUpViewPagerIcons(tabLayout);
        }

        private void setUpViewPagerIcons(TabLayout tabLayout) {
            for(int i=0;i<tabLayout.getTabCount();i++){
                int iconId=-1;
                switch (i){
                    case 0:
                        iconId = R.drawable.ic_cast_on_0_light;
                        break;
                    case 1:
                        iconId = R.drawable.ic_cast_on_0_light;
                        break;
                    case 2:
                        iconId = R.drawable.ic_cast_on_0_light;
                        break;
                    case 3:
                        iconId = R.drawable.ic_cast_on_0_light;
                        break;
                }

                TintableImageView tab1 = (TintableImageView) LayoutInflater.from(this).inflate(R.layout.tint_layout, null);
                tab1.setImageResource(iconId);

                tabLayout.getTabAt(i).setCustomView(tab1);
            }
        }



        /**
         * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
         * one of the sections/tabs/pages.
         */
        public class JobDetailPagerAdapter extends FragmentPagerAdapter {

        // old code


        @Override
        public CharSequence getPageTitle(int position) {
            return "";
        }
    }

}

我希望它能对某人有所帮助,我为此浪费了一天时间。