使用 PageChangeListener 动态更改选项卡图标的颜色
Dynamically change tab icons' color with PageChangeListener
我想像 Facebook 应用一样更改标签图标的颜色。
当ViewPager
's state is SCROLL_STATE_DRAGGING
, then change all icons'颜色为未选择(灰色)颜色时,另一方面,当ViewPager
的状态为SCROLL_STATE_SETTLING
和SCROLL_STATE_IDLE
,然后将所选选项卡的图标更改为所选(白色)颜色。
我做了一个测试:将当前选中的片段滚动到其他片段,但仍然保持SCROLL_STATE_DRAGGING
状态。
这是一个 st运行ge 情况,我 运行 模拟器上的应用程序似乎运行良好,但是当我 运行 真实设备上的应用程序时,它当 ViewPager
状态为 SCROLL_STATE_IDLE
或 SCROLL_STATE_SETTLING
.
时,未将所选选项卡的颜色更改为白色
我在ViewPager
中加了一个addOnPageChangeListener
,并且在不同的状态下改变了颜色。
有什么建议吗?
这是我的代码:
void setupViews() {
mViewPager = (ViewPager) findViewById(R.id.container);
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
colorSelected = ContextCompat.getColor(ctx, R.color.itemSelected);//white
colorUnselected = ContextCompat.getColor(ctx, R.color.itemUnselected);//gray
pagerIcons = new Drawable[2];
pagerIcons[0] = DrawableCompat.wrap(VectorDrawableCompat.create(ctx.getResources(), R.drawable.ic_list_black_24dp, null));
pagerIcons[1] = DrawableCompat.wrap(VectorDrawableCompat.create(ctx.getResources(), R.drawable.ic_shopping_cart_black_24dp, null));
ViewPagerHelper.TabOption option = new ViewPagerHelper.TabOption(true, true);
helper = new ViewPagerHelper(getSupportFragmentManager(), mViewPager, tabLayout, option);
helper.bindViewPager();
helper.addFragmentWithTabIcon(new ExpenseIncomeFragment(), pagerIcons[0], ExpenseIncomeFragment.TAG);
helper.addFragmentWithTabIcon(new FragmentWishList(), pagerIcons[1], FragmentWishList.TAG);
mViewPager.setScrollbarFadingEnabled(true);
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//if (positionOffset>0)DrawableCompat.setTint(pagerIcons[mViewPager.getCurrentItem()], colorUnselected);
Log.e("MainActivity","position="+position+"
positionOffset="+positionOffset+" positionOffsetPixels="+positionOffsetPixels);
}
@Override
public void onPageSelected(int position) {
Log.e("MainActivity","position="+position);
pagerIcons[mViewPager.getCurrentItem()].setColorFilter(colorSelected, PorterDuff.Mode.SRC_IN);
}
@Override
public void onPageScrollStateChanged(int state) {
int pos = mViewPager.getCurrentItem();
switch (state) {
case ViewPager.SCROLL_STATE_IDLE:
Log.e("MainActivity","SCROLL_STATE_IDLE" + " getCurrentItem="+pos);
pagerIcons[pos].setColorFilter(colorSelected, PorterDuff.Mode.SRC_IN);
break;
case ViewPager.SCROLL_STATE_DRAGGING:
Log.e("MainActivity","SCROLL_STATE_DRAGGING" + " getCurrentItem="+pos);
pagerIcons[pos].setColorFilter(colorUnselected, PorterDuff.Mode.SRC_IN);
break;
case ViewPager.SCROLL_STATE_SETTLING:
Log.e("MainActivity","SCROLL_STATE_SETTLING" + " getCurrentItem="+pos);
pagerIcons[pos].setColorFilter(colorSelected, PorterDuff.Mode.SRC_IN);
break;
}
}
});
helper.update();
mViewPager.setCurrentItem(0);
int len = pagerIcons.length;
for (int i = 0; i < len; i++) {
pagerIcons[i].setColorFilter(colorUnselected,
PorterDuff.Mode.SRC_IN);
}
pagerIcons[0].setColorFilter(colorSelected,PorterDuff.Mode.SRC_IN);
});
}
class ViewPagerHelper
用于将 ViewPager
绑定到 TabLayout
。
pagerIcons
是选项卡图标的可绘制对象,我为它们着色。
由于您使用的是矢量可绘制对象,因此您可以通过不同的方式解决此问题。你可以摆脱整个 OnPageChangeListener
并只留下这个:
void setupViews() {
mViewPager = (ViewPager) findViewById(R.id.container);
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
pagerIcons = new Drawable[2];
pagerIcons[0] = VectorDrawableCompat.create(ctx.getResources(), R.drawable.ic_list_black_24dp, null);
pagerIcons[1] = VectorDrawableCompat.create(ctx.getResources(), R.drawable.ic_shopping_cart_black_24dp, null);
ViewPagerHelper.TabOption option = new ViewPagerHelper.TabOption(true, true);
helper = new ViewPagerHelper(getSupportFragmentManager(), mViewPager, tabLayout, option);
helper.bindViewPager();
helper.addFragmentWithTabIcon(new ExpenseIncomeFragment(), pagerIcons[0], ExpenseIncomeFragment.TAG);
helper.addFragmentWithTabIcon(new FragmentWishList(), pagerIcons[1], FragmentWishList.TAG);
mViewPager.setScrollbarFadingEnabled(true);
helper.update();
mViewPager.setCurrentItem(0);
}
与其尝试管理 Java 中图标的颜色,您可以让系统通过在 <vector>
可绘制对象本身中管理它们来为您完成。首先,在您的 res/color/
目录中创建一个颜色选择器文件:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/itemSelected" android:state_selected="true"/>
<item android:color="@color/itemUnselected"/>
</selector>
然后在你的矢量文件中使用这种颜色:
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="@color/my_color_selector"
android:pathData="M3,13h2v-2L3,11v2zM3,17h2v-2L3,15v2zM3,9h2L5,7L3,7v2zM7,13h14v-2L7,11v2zM7,17h14v-2L7,15v2zM7,7v2h14L21,7L7,7z"/>
</vector>
如果您需要支持 21 以下的 API 级别,则不能直接在向量中使用颜色选择器。相反,为每个矢量可绘制对象创建两个副本,一个具有选定的颜色,一个具有未选定的颜色。然后在 Java 中构建一个 StateListDrawable
并将其分配给您的 pagerIcons
数组:
Drawable selected0 = ContextCompat.getDrawable(this, R.drawable.ic_list_black_24dp_selected);
Drawable unselected0 = ContextCompat.getDrawable(this, R.drawable.ic_list_black_24dp_unselected);
StateListDrawable statelist0 = new StateListDrawable();
statelist0.addState(new int[]{android.R.attr.state_selected}, selected0);
statelist0.addState(StateSet.WILD_CARD, unselected0);
pagerIcons[0] = statelist0;
无论您是否可以在 XML 中使用颜色选择器或必须在 Java 中构建 StateListDrawable,根本概念都是相同的:让 Android 框架决定哪个选项卡被选中,让它为您着色。
我想像 Facebook 应用一样更改标签图标的颜色。
当ViewPager
's state is SCROLL_STATE_DRAGGING
, then change all icons'颜色为未选择(灰色)颜色时,另一方面,当ViewPager
的状态为SCROLL_STATE_SETTLING
和SCROLL_STATE_IDLE
,然后将所选选项卡的图标更改为所选(白色)颜色。
我做了一个测试:将当前选中的片段滚动到其他片段,但仍然保持SCROLL_STATE_DRAGGING
状态。
这是一个 st运行ge 情况,我 运行 模拟器上的应用程序似乎运行良好,但是当我 运行 真实设备上的应用程序时,它当 ViewPager
状态为 SCROLL_STATE_IDLE
或 SCROLL_STATE_SETTLING
.
我在ViewPager
中加了一个addOnPageChangeListener
,并且在不同的状态下改变了颜色。
有什么建议吗?
这是我的代码:
void setupViews() {
mViewPager = (ViewPager) findViewById(R.id.container);
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
colorSelected = ContextCompat.getColor(ctx, R.color.itemSelected);//white
colorUnselected = ContextCompat.getColor(ctx, R.color.itemUnselected);//gray
pagerIcons = new Drawable[2];
pagerIcons[0] = DrawableCompat.wrap(VectorDrawableCompat.create(ctx.getResources(), R.drawable.ic_list_black_24dp, null));
pagerIcons[1] = DrawableCompat.wrap(VectorDrawableCompat.create(ctx.getResources(), R.drawable.ic_shopping_cart_black_24dp, null));
ViewPagerHelper.TabOption option = new ViewPagerHelper.TabOption(true, true);
helper = new ViewPagerHelper(getSupportFragmentManager(), mViewPager, tabLayout, option);
helper.bindViewPager();
helper.addFragmentWithTabIcon(new ExpenseIncomeFragment(), pagerIcons[0], ExpenseIncomeFragment.TAG);
helper.addFragmentWithTabIcon(new FragmentWishList(), pagerIcons[1], FragmentWishList.TAG);
mViewPager.setScrollbarFadingEnabled(true);
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//if (positionOffset>0)DrawableCompat.setTint(pagerIcons[mViewPager.getCurrentItem()], colorUnselected);
Log.e("MainActivity","position="+position+"
positionOffset="+positionOffset+" positionOffsetPixels="+positionOffsetPixels);
}
@Override
public void onPageSelected(int position) {
Log.e("MainActivity","position="+position);
pagerIcons[mViewPager.getCurrentItem()].setColorFilter(colorSelected, PorterDuff.Mode.SRC_IN);
}
@Override
public void onPageScrollStateChanged(int state) {
int pos = mViewPager.getCurrentItem();
switch (state) {
case ViewPager.SCROLL_STATE_IDLE:
Log.e("MainActivity","SCROLL_STATE_IDLE" + " getCurrentItem="+pos);
pagerIcons[pos].setColorFilter(colorSelected, PorterDuff.Mode.SRC_IN);
break;
case ViewPager.SCROLL_STATE_DRAGGING:
Log.e("MainActivity","SCROLL_STATE_DRAGGING" + " getCurrentItem="+pos);
pagerIcons[pos].setColorFilter(colorUnselected, PorterDuff.Mode.SRC_IN);
break;
case ViewPager.SCROLL_STATE_SETTLING:
Log.e("MainActivity","SCROLL_STATE_SETTLING" + " getCurrentItem="+pos);
pagerIcons[pos].setColorFilter(colorSelected, PorterDuff.Mode.SRC_IN);
break;
}
}
});
helper.update();
mViewPager.setCurrentItem(0);
int len = pagerIcons.length;
for (int i = 0; i < len; i++) {
pagerIcons[i].setColorFilter(colorUnselected,
PorterDuff.Mode.SRC_IN);
}
pagerIcons[0].setColorFilter(colorSelected,PorterDuff.Mode.SRC_IN);
});
}
class ViewPagerHelper
用于将 ViewPager
绑定到 TabLayout
。
pagerIcons
是选项卡图标的可绘制对象,我为它们着色。
由于您使用的是矢量可绘制对象,因此您可以通过不同的方式解决此问题。你可以摆脱整个 OnPageChangeListener
并只留下这个:
void setupViews() {
mViewPager = (ViewPager) findViewById(R.id.container);
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
pagerIcons = new Drawable[2];
pagerIcons[0] = VectorDrawableCompat.create(ctx.getResources(), R.drawable.ic_list_black_24dp, null);
pagerIcons[1] = VectorDrawableCompat.create(ctx.getResources(), R.drawable.ic_shopping_cart_black_24dp, null);
ViewPagerHelper.TabOption option = new ViewPagerHelper.TabOption(true, true);
helper = new ViewPagerHelper(getSupportFragmentManager(), mViewPager, tabLayout, option);
helper.bindViewPager();
helper.addFragmentWithTabIcon(new ExpenseIncomeFragment(), pagerIcons[0], ExpenseIncomeFragment.TAG);
helper.addFragmentWithTabIcon(new FragmentWishList(), pagerIcons[1], FragmentWishList.TAG);
mViewPager.setScrollbarFadingEnabled(true);
helper.update();
mViewPager.setCurrentItem(0);
}
与其尝试管理 Java 中图标的颜色,您可以让系统通过在 <vector>
可绘制对象本身中管理它们来为您完成。首先,在您的 res/color/
目录中创建一个颜色选择器文件:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/itemSelected" android:state_selected="true"/>
<item android:color="@color/itemUnselected"/>
</selector>
然后在你的矢量文件中使用这种颜色:
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="@color/my_color_selector"
android:pathData="M3,13h2v-2L3,11v2zM3,17h2v-2L3,15v2zM3,9h2L5,7L3,7v2zM7,13h14v-2L7,11v2zM7,17h14v-2L7,15v2zM7,7v2h14L21,7L7,7z"/>
</vector>
如果您需要支持 21 以下的 API 级别,则不能直接在向量中使用颜色选择器。相反,为每个矢量可绘制对象创建两个副本,一个具有选定的颜色,一个具有未选定的颜色。然后在 Java 中构建一个 StateListDrawable
并将其分配给您的 pagerIcons
数组:
Drawable selected0 = ContextCompat.getDrawable(this, R.drawable.ic_list_black_24dp_selected);
Drawable unselected0 = ContextCompat.getDrawable(this, R.drawable.ic_list_black_24dp_unselected);
StateListDrawable statelist0 = new StateListDrawable();
statelist0.addState(new int[]{android.R.attr.state_selected}, selected0);
statelist0.addState(StateSet.WILD_CARD, unselected0);
pagerIcons[0] = statelist0;
无论您是否可以在 XML 中使用颜色选择器或必须在 Java 中构建 StateListDrawable,根本概念都是相同的:让 Android 框架决定哪个选项卡被选中,让它为您着色。