pressed/focused/selected/etcのときにDrawableが強調表示される一般的なフレームワーク関数を作成しようとしています。
私の関数はDrawableを取り、StateListDrawableを返します。デフォルトの状態はDrawableそのものであり、_Android.R.attr.state_pressed
_の状態は、setColorFilter
を使用してフィルタが適用されただけの同じDrawableです。
私の問題は、ドロウアブルのクローンを作成して、フィルターを適用した別のインスタンスを作成できないことです。ここに私が達成しようとしているものがあります:
_StateListDrawable makeHighlightable(Drawable drawable)
{
StateListDrawable res = new StateListDrawable();
Drawable clone = drawable.clone(); // how do I do this??
clone.setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
res.addState(new int[] {Android.R.attr.state_pressed}, clone);
res.addState(new int[] { }, drawable);
return res;
}
_
クローンを作成しない場合、フィルタは明らかに両方の状態に適用されます。 mutate()
で遊んでみましたが、助けにはなりません。
何か案は?
更新:
受け入れられた答えは確かにドロアブルを複製します。私の一般的な機能が別の問題で失敗するので、それは私を助けませんでした。 StateListにドロアブルを追加すると、すべてのフィルターが失われるようです。
以下を試してください:
Drawable clone = drawable.getConstantState().newDrawable();
getConstantState().newDrawable()
で作成されたドロアブルにフィルター/などを適用すると、ドロアブルはconstantState
をキャッシュとして使用するため、そのドロアブルのすべてのインスタンスも変更されます!
したがって、カラーフィルターとnewDrawable()
を使用して円に色を付けると、すべての円の色が変わります。
他のインスタンスに影響を与えずにこのドロウアブルを更新可能にしたい場合は、既存の定数状態を変更する必要があります。
// To make a drawable use a separate constant state
drawable.mutate()
適切な説明については、以下を参照してください。
http://www.curious-creature.org/2009/05/02/drawable-mutations/
http://developer.Android.com/reference/Android/graphics/drawable/Drawable.html#mutate()
これは私のために働くものです。
Drawable clone = drawable.getConstantState().newDrawable().mutate();
これはこれに基づく私の解決策です SOの質問 。
アイデアは、ImageView
はユーザーがタッチするとカラーフィルターを取得し、ユーザーがタッチを停止するとカラーフィルターが削除されるというものです。メモリ内には1つのドロウアブル/ビットマップのみがあるため、無駄にする必要はありません。正常に機能します。
class PressedEffectStateListDrawable extends StateListDrawable {
private int selectionColor;
public PressedEffectStateListDrawable(Drawable drawable, int selectionColor) {
super();
this.selectionColor = selectionColor;
addState(new int[] { Android.R.attr.state_pressed }, drawable);
addState(new int[] {}, drawable);
}
@Override
protected boolean onStateChange(int[] states) {
boolean isStatePressedInArray = false;
for (int state : states) {
if (state == Android.R.attr.state_pressed) {
isStatePressedInArray = true;
}
}
if (isStatePressedInArray) {
super.setColorFilter(selectionColor, PorterDuff.Mode.MULTIPLY);
} else {
super.clearColorFilter();
}
return super.onStateChange(states);
}
@Override
public boolean isStateful() {
return true;
}
}
使用法:
Drawable drawable = new FastBitmapDrawable(bm);
imageView.setImageDrawable(new PressedEffectStateListDrawable(drawable, 0xFF33b5e5));
関連する質問に答えました こちら
基本的に、StateListDrawablesは実際にフィルターを失っているようです。最初に使用したいビットマップの変更されたコピーから新しいBitmapDrawaleを作成しました。