我想创建自定义按钮以在 TabHost 中使用。我一直在尝试只使用相同的图像资源 (png),但根据状态改变滤色器。所以我做了这个作为自定义按钮的布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<ImageView android:id="@+id/tab_icon"
android:layout_centerInParent="true" android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView android:id="@+id/tab_text" android:layout_below="@id/tab_icon"
android:layout_centerHorizontal="true" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
在我的 Activity 中,我添加了这样的标签:
tabHost.addTab(tabHost.newTabSpec(TAB_NAME_NEWS).setIndicator(buildTab(R.drawable.tab_icon_news, R.string.news))
.setContent(newsIntent));
这是“buildTab”方法:
private final static int[] SELECTED = new int[] { android.R.attr.state_selected };
private final static int[] IDLE = new int[] { -android.R.attr.state_selected };
private View buildTab(int icon, int label) {
LayoutInflater inflater = LayoutInflater.from(this);
View view = inflater.inflate(R.layout.tab_button, null);
StateListDrawable drawable = new StateListDrawable();
Drawable selected = getResources().getDrawable(icon);
selected.mutate();
selected.setBounds(0, 0, selected.getIntrinsicWidth(), selected.getIntrinsicHeight());
selected.setColorFilter(new LightingColorFilter(0xFFFFFFFF, 0x0000FF00));
drawable.addState(SELECTED, selected);
Drawable idle = getResources().getDrawable(icon);
idle.mutate();
idle.setColorFilter(new LightingColorFilter(0xFFFFFFFF, 0x000000FF));
drawable.addState(IDLE, idle);
((ImageView) view.findViewById(R.id.tab_icon)).setImageDrawable(drawable);
((TextView) view.findViewById(R.id.tab_text)).setText(getString(label));
return view;
}
在选中状态下,图像应该是完全绿色的(0x0000FF00
),在非选中状态下,它应该是蓝色的(0x000000FF
)。
问题是滤色器似乎被完全忽略了。在任何情况下我都看不到颜色发生变化。
我也尝试通过设置 android:tint
来获得相同的结果<ImageView/>
上的属性(property), 但显然你不能使用对 <selector>
的引用在那里,因为它抛出一个 NumberFormatException
.
我看不出我做错了什么,所以我们将不胜感激。
最佳答案
好吧,我从来没有让上面的代码工作,所以这就是我最终做的。
首先,我将 LayerDrawable 子类化:
public class StateDrawable extends LayerDrawable {
public StateDrawable(Drawable[] layers) {
super(layers);
}
@Override
protected boolean onStateChange(int[] states) {
for (int state : states) {
if (state == android.R.attr.state_selected) {
super.setColorFilter(Color.argb(255, 255, 195, 0), PorterDuff.Mode.SRC_ATOP);
} else {
super.setColorFilter(Color.GRAY, PorterDuff.Mode.SRC_ATOP);
}
}
return super.onStateChange(states);
}
@Override
public boolean isStateful() {
return true;
}
}
我将 buildTab()
方法更改为以下内容:
private View buildTab(int icon, int label) {
LayoutInflater inflater = LayoutInflater.from(this);
View view = inflater.inflate(R.layout.tab_button, null);
((ImageView) view.findViewById(R.id.tab_icon)).setImageDrawable(new StateDrawable(new Drawable[] { getResources()
.getDrawable(icon) }));
((TextView) view.findViewById(R.id.tab_text)).setText(getString(label));
return view;
}
我仍然像这样添加标签:
Intent fooIntent = new Intent().setClass(this, FooActivity.class);
tabHost.addTab(tabHost.newTabSpec(TAB_NAME_INFO).setIndicator(buildTab(R.drawable.tab_icon_info, R.string.info)).setContent(infoIntent));
这对我有用,与 android 1.6 兼容。
关于java - StateListDrawable 切换滤色器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6018602/