如何为 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 教程。
您可以使用 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 "";
}
}
}
我希望它能对某人有所帮助,我为此浪费了一天时间。
我正在实现一个带图标的 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 教程。
您可以使用 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 "";
}
}
}
我希望它能对某人有所帮助,我为此浪费了一天时间。