プログラムで行うのではなく、xmlを使用してtabhostのアイコンに色を付けたい(とにかくそれを行うことができなかった)...だから私はSOでこのスレッドを見つけました: Android imageviewは色合いを変更してボタンクリックをシミュレートします
それはかなり良い解決策のように思えますが、私のプロジェクトでそれを正しく適応させることができませんでした...私は次の変更を行いました:
public class TintableImageView extends ImageView {
private ColorStateList tint;
public TintableImageView(Context context) {
super(context);
}
//this is the constructor that causes the exception
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);
}
//here, obtainStyledAttributes was asking for an array
private void init(Context context, AttributeSet attrs, int defStyle) {
TypedArray a = context.obtainStyledAttributes(attrs, new int[]{R.styleable.TintableImageView_tint}, defStyle, 0);
tint = a.getColorStateList(R.styleable.TintableImageView_tint);
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);
}
}
@drawable/selector.xml
でAndroid:tint
を参照することもできなかったため、colors.xmlでこれを行いました。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="azulPadrao">#2e7cb4</color>
<drawable name="tab_icon_selector">@drawable/tab_icon_selector</drawable>
</resources>
私のセレクター:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item Android:state_selected="true" Android:tint="#007AFF" />
<item Android:state_focused="true" Android:tint="#007AFF" />
<item Android:state_pressed="true" Android:tint="#007AFF" />
<item Android:tint="#929292" />
</selector>
私のタブレイアウト:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:orientation="vertical" Android:id="@+id/TabLayout"
Android:layout_width="fill_parent" Android:layout_height="fill_parent"
Android:gravity="center" Android:background="@drawable/tab_bg_selector">
<com.myapp.TintableImageView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:id="@+id/imageView" Android:layout_gravity="center" Android:tint="@drawable/tab_icon_selector"/>
<TextView Android:id="@+id/TabTextView" Android:text="Text"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content" Android:textColor="@drawable/tab_text_selector"
Android:textSize="10dip"
Android:textStyle="bold" Android:layout_marginTop="2dip"/>
</LinearLayout>
助言がありますか?前もって感謝します
[編集] Android:tint
(app:tint
を設定した後)が正しいときにxmlns:app="http://schemas.Android.com/apk/res/com.myapp"
を使用するためにNumberFormatException
を取得していましたが、今は使用していると思いますセレクタが間違った方法で、アイコンが状態に関係なくすべて黒であるため...私はcolors.xml内から<drawable name="tab_icon_selector">@drawable/tab_icon_selector</drawable>
を設定しようとしましたが、動作しません
[/編集]
https://stackoverflow.com/a/18724834/2136792 にある私のソリューションを参照すると、不足していることがいくつかあります。
TintableImageView.Java
@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);
}
drawableStateChanged()は、要素の状態が変化したときに色合いが更新されるようにオーバーライドする必要があります。
ドロアブルからドロアブルを参照することで問題が発生するかどうかはわかりませんが、selector.xmlを「/ res/color」フォルダーに移動して、「@ color/selector.xml」で参照できます(aapt merges /res/values/colors.xmlと/ res/colorフォルダーの両方)。
API 21+を使用している場合は、セレクタと tint を使用してXMLで簡単にこれを行うことができます。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item Android:state_activated="true">
<bitmap Android:src="@drawable/ic_settings_grey"
Android:tint="@color/primary" />
</item>
<item Android:drawable="@drawable/ic_settings_grey"/>
</selector>
これは、Android support-v4ライブラリからの DrawableCompat
を使用して実装しました。
通常のImageButton
(ImageView
をサブクラス化するため、この情報はImageView
sにも適用されます)で、 素材アイコンコレクション の黒いアイコンを使用します。
_<ImageButton
Android:id="@+id/button_add"
Android:src="@drawable/ic_add_black_36dp"
Android:background="?attr/selectableItemBackgroundBorderless"
Android:contentDescription="@string/title_add_item" />
_
これは私が作成したユーティリティメソッドです。
_public static void tintButton(@NonNull ImageButton button) {
ColorStateList colours = button.getResources()
.getColorStateList(R.color.button_colour);
Drawable d = DrawableCompat.wrap(button.getDrawable());
DrawableCompat.setTintList(d, colours);
button.setImageDrawable(d);
}
_
_res/color/button_colour.xml
_は、ボタンが押されたときにアイコンの色を赤から半透明の赤に変更するセレクターです。
_<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item
Android:state_pressed="false"
Android:color="@color/red" />
<item
Android:color="@color/red_alpha_50pc" />
</selector>
_
アクティビティのonCreate()
メソッドでImageButton
が膨らんだ後、ボタンごとにtintButton(...)
ヘルパーメソッドを呼び出すだけです。
これをAndroid 4.1(my minSdkVersion
)および5.0デバイスでテストしましたが、DrawableCompat
はAndroid 1.6。
サポートライブラリ22.1では、DrawableCompatを使用して、Drawable、APIレベル4+
DrawableCompat.wrap(Drawable)およびsetTint()、setTintList()、およびsetTintMode()は機能します。複数の色をサポートするためだけに、個別のドロウアブルを作成および維持する必要はありません!
コードの@Dreamingに同意し、例を挙げます。
ic_up_small
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item Android:color="@color/comment_count_selected_color" Android:state_selected="true" />
<item Android:color="@color/comment_count_text_color"/>
</selector>
layout/item_post_count_info.xml
<Android.support.v7.widget.AppCompatImageView
Android:id="@+id/post_upvote_icon"
Android:layout_width="14dp"
Android:layout_height="14dp"
Android:layout_marginLeft="17dp"
app:srcCompat="@drawable/ic_up_small"
app:tint="@color/post_up_color"/>
注意:Android:tintの代わりにapp:tintを使用する必要があります。
サポートライブラリのバージョンは26.0.2です。
app/build.gradle
implementation 'com.Android.support:appcompat-v7:26.0.2'
implementation 'com.Android.support:support-core-utils:26.0.2'
implementation 'com.Android.support:support-annotations:26.0.2'
implementation 'com.Android.support:support-v4:26.0.2'
implementation 'com.Android.support:design:26.0.2'
Android:tintを使用すると、クラッシュし、ログは次のようになります。
E/AndroidRuntime:FATAL EXCEPTION:main Android.view.InflateException:Binary XML file line#0:Error inflating class at Android.view.LayoutInflater.createView(LayoutInflater.Java:613)at Android.view.LayoutInflater.createViewFromTag(LayoutInflater。 Java:687)at Android.view.LayoutInflater.rInflate(LayoutInflater.Java:746)at Android.view.LayoutInflater.inflate(LayoutInflater.Java:489)at Android.view.LayoutInflater.inflate(LayoutInflater.Java:396)at com.opera.six.viewholder.post.PostCountInfoViewHolder $ 1.create(PostCountInfoViewHolder.Java:29)at com.opera.six.viewholder.post.PostCountInfoViewHolder $ 1.create(PostCountInfoViewHolder.Java:25)at com.opera.six。 collection.CollectionAdapter.onCreateViewHolder(CollectionAdapter.Java:39)at com.opera.six.collection.CollectionAdapter.onCreateViewHolder(CollectionAdapter.Java:19)at Android.support.v7.widget.RecyclerView $ Adapter.createViewHolder(RecyclerView.Java: 6493)at Android.support.v7.widget.RecyclerView $ Recycler.tryGetViewHolderForPosit ionByDeadline(RecyclerView.Java:5680)at Android.support.v7.widget.RecyclerView $ Recycler.getViewForPosition(RecyclerView.Java:5563)at Android.support.v7.widget.RecyclerView $ Recycler.getViewForPosition(RecyclerView.Java:5559) Android.support.v7.widget.LinearLayoutManager $ LayoutState.next(LinearLayoutManager.Java:2229)at Android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.Java:1556)at Android.support.v7.widget.LinearLayoutManager AndroidのAndroid.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.Java:608)のAndroid.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.Java:3693)の.fill(LinearLayoutManager.Java:1516) support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.Java:3410)at Android.support.v7.widget.RecyclerView.onLayout(RecyclerView.Java:3962)at Android.view.View.layout(View.Java:13754) Android.view.ViewGroup.layout(ViewGroup.Java:4364)at Android.support.v4.widget.SwipeRefreshLayout.onLayout(SwipeR efreshLayout.Java:610)at Android.view.View.layout(View.Java:13754)at Android.view.ViewGroup.layout(ViewGroup.Java:4364)at Android.support.design.widget.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior .Java:132)at Android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.Java:42)at Android.support.design.widget.AppBarLayout $ ScrollingViewBehavior.onLayoutChild(AppBarLayout.Java:1361)at Android.support。 design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.Java:869)at Android.view.View.layout(View.Java:13754)at Android.view.ViewGroup.layout(ViewGroup.Java:4364)at Android.support.v4 .view.ViewPager.onLayout(ViewPager.Java:1767)at Android.view.View.layout(View.Java:13754)at Android.view.ViewGroup.layout(ViewGroup.Java:4364)at Android.widget.LinearLayout。 setChildFrame(LinearLayout.Java:1649)at Android.widget.LinearLayout.layoutVertical(LinearLayout.Java:1507)at Android.widget.LinearLayout.onLayout(LinearLayout.Java:1420)at Android。 view.View.layout(View.Java:13754)at Android.view.ViewGroup.layout(ViewGroup.Java:4364)at Android.widget.FrameLayout.onLayout(FrameLayout.Java:448)at Android.view.View.layout (View.Java:13754)Android.view.ViewGroup.layout(ViewGroup.Java:4364)at Android.widget.FrameLayout.onLayout(FrameLayout.Java:448)at Android.view.View.layout(View.Java: 13754)Android.view.ViewGroup.layout(ViewGroup.Java:4364)at Android.widget.LinearLayout.setChildFrame(LinearLayout.Java:1649)at Android.widget.LinearLayout.layoutVertical(LinearLayout.Java:1507)at Android。 widget.LinearLayout.onLayout(LinearLayout.Java:1420)at Android.view.View.layout(View.Java:13754)at Android.view.ViewGroup.layout(ViewGroup.Java:4364)at Android.widget.FrameLayout.onLayout (FrameLayout.Java:448)Android.view.View.layout(View.Java:13754)at Android.view.ViewGroup.layout(ViewGroup.Java:4364)at Android.widget.FrameLayout.onLayout(FrameLayout.Java: 448)Android.view.View.layout(View.Java:13754)at Android.view.ViewGrou p.layout(Vi
現在のAppCompatサポートライブラリでは、app:tint
on ImageView
タグ。AppCompatImageView
として膨張し、状態の変化を適切に処理します。
AppCompatImageView
で、mImageHelper
に状態の変更が通知されていることがわかります。
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
if (mBackgroundTintHelper != null) {
mBackgroundTintHelper.applySupportBackgroundTint();
}
if (mImageHelper != null) {
mImageHelper.applySupportImageTint();
}
}
Android Studioは現在これについて警告を出しますが、安全に抑制することができます。