画面のスクロールに合わせてToolbarの背景アルファを動的に変更していて気づいたこと。
「内容が同じDrawableはいろんなところで同一インスタンスを参照している」
Androidガッツリやってる人からすると常識的なことかも知れませんが、普段あんまり意識してませんでした。
Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
mToolbar.getBackgroundDrawable().setAlpha(0.1f);
みたいな感じで(実際はもうちょっときちんと書いてますが)処理を書くと、Toolbarの背景と同じ背景色を指定しているViewが軒並み透過してしまいました。確認できたのはNexus5(Lollipop)なので、バージョン依存でしょうか。同じActivityだけじゃなく、別Activityでも同一のThemeを設定している場合は上記の影響がそのまま残ってしまう模様。
Toolbarの背景なんてだいたいcolorPrimary指定してるから、影響でかくてちょっと焦ってしまいました。
今回は以下のように書いて回避。もうちょいいい方法ないかな?
@Override
protected void onCreate(Bundle savedInstanceState) {
// いろいろ初期化
// 明示的にDrawableをnewしてToolbarの背景に設定する。
Drawable drawable = new ColorDrawable(getResources().getColor(R.color.toolbar_bg));
mToolbar.setBackground(drawable);
}
ViewTreeObserverとか使わないとダメかもと思いましたが、ひとまずこれで動いてるので、まあよし。
2015/02/13 追記
コメント欄で指摘していただきましたが、Drawable.mutate()で変更を他の箇所に影響させない、ということができるようでした。
インスタンスを複製するわけじゃなく、Constant stateに変更を通知させないって理解でいいのかな。
mToolbar.getBackground().mutate().setAlpha(0.1f);
みたいな。コードすっきりした!