- http://tools.oesf.biz/android-5.0.1_r1.0/xref/frameworks/support/v7/appcompat/src/android/support/v7/internal/widget/TintManager.java
- http://tools.oesf.biz/android-5.0.1_r1.0/xref/frameworks/support/v7/appcompat/src/android/support/v7/internal/widget/TintDrawableWrapper.java
- http://tools.oesf.biz/android-5.0.1_r1.0/xref/frameworks/support/v7/appcompat/src/android/support/v7/internal/widget/DrawableWrapper.java
- http://tools.oesf.biz/android-5.0.1_r1.0/xref/frameworks/support/v7/appcompat/src/android/support/v7/internal/widget/TintResources.java
- http://tools.oesf.biz/android-5.0.1_r1.0/xref/frameworks/support/v7/appcompat/src/android/support/v7/internal/widget/TintTypedArray.java
2015年1月13日火曜日
AppCompat v7 で tint 処理しているクラスとか
メモ
Android 5.0 で EditText の normal 時の色を独自に変える
以前のエントリ「Android 5.0 でのカラーカスタマイズと属性名の関係」で書いたように、EditText の normal 時の線の色は colorControlNormal になります。
colorControlNormal にはデフォルトでは textColorSecondary が指定されており、Theme.Material では @color/secondary_text_material_dark、Theme.Material.Light では @color/secondary_text_material_light になります。
これらの normal 時の色は最終的に以下になります。
実際にこの色の EditText を配置してみると、Material Design の Components > Text fields で例としてあげられている画像の色より、かなり濃いことがわかります。
colorControlNormal に薄いグレーを指定すれば、EditText の normal 時の色を変えられますが、この属性はさまざまなところで使われており、例えば CheckBox の normal 時の色も薄くなってしまいます。
colorControlNormal ではなく独自に色を指定したい場合、残念ながら用意されている属性値ではできません。 EditText の背景を独自のリソースに変える必要があります。
EditText の 5.0 でのデフォルト背景は次のようになっています。
android:drawable/edit_text_material.xml
これを参考に、AppCompat の画像リソースを利用して次のようにします。
drawable-v21/my_edit_text_material.xml
values/attr.xml
colorControlNormal にはデフォルトでは textColorSecondary が指定されており、Theme.Material では @color/secondary_text_material_dark、Theme.Material.Light では @color/secondary_text_material_light になります。
これらの normal 時の色は最終的に以下になります。
#b3ffffff
#8a000000
つまり、Theme.Material.Light では線の色は #8a000000 です。
実際にこの色の EditText を配置してみると、Material Design の Components > Text fields で例としてあげられている画像の色より、かなり濃いことがわかります。
colorControlNormal に薄いグレーを指定すれば、EditText の normal 時の色を変えられますが、この属性はさまざまなところで使われており、例えば CheckBox の normal 時の色も薄くなってしまいます。
colorControlNormal ではなく独自に色を指定したい場合、残念ながら用意されている属性値ではできません。 EditText の背景を独自のリソースに変える必要があります。
EditText の 5.0 でのデフォルト背景は次のようになっています。
android:drawable/edit_text_material.xml
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:inset="@dimen/control_inset_material">
<ripple android:color="?attr/colorControlActivated">
<item>
<selector>
<item android:state_enabled="false">
<nine-patch android:src="@drawable/textfield_default_mtrl_alpha"
android:tint="?attr/colorControlNormal"
android:alpha="?attr/disabledAlpha" />
</item>
<item>
<nine-patch android:src="@drawable/textfield_default_mtrl_alpha"
android:tint="?attr/colorControlNormal" />
</item>
</selector>
</item>
<item android:id="@+id/mask" android:drawable="@drawable/textfield_activated_mtrl_alpha" />
</ripple>
</inset>
これを参考に、AppCompat の画像リソースを利用して次のようにします。
drawable-v21/my_edit_text_material.xml
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:inset="@dimen/control_inset_material">
<ripple android:color="?attr/colorControlActivated">
<item>
<selector>
<item android:state_enabled="false">
<nine-patch android:src="@drawable/abc_textfield_default_mtrl_alpha"
android:tint="?attr/colorEditTextNormal"
android:alpha="?android:attr/disabledAlpha" />
</item>
<item>
<nine-patch android:src="@drawable/abc_textfield_default_mtrl_alpha"
android:tint="?attr/colorEditTextNormal" />
</item>
</selector>
</item>
<item android:id="@android:id/mask" android:drawable="@drawable/abc_textfield_activated_mtrl_alpha" />
</ripple>
</inset>
ここでは、?attr/colorControlNormal の代わりに ?attr/colorEditTextNormal を指定しています。
values/attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="colorEditTextNormal" format="color|reference" />
</resources>
values-v21/styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="editTextBackground">@drawable/my_edit_text_material</item>
<item name="colorEditTextNormal">#1f000000</item>
</style>
</resources>
Material Design の Resources > Sticker sheets & icons で配布されている stickersheet_general.ai では、EditText の色は divider と同じ #000000 の alpha 12% でした。
Android 5.0 でのカラーカスタマイズと属性名の関係
CheckBox
RadioButton
Switch
thumb
track
RatingBar
ratingbar_full_filled_material.xml
EditText
Text選択
text_select_handle_left_material.xml
text_select_handle_middle_material.xml
text_select_handle_right_material.xml
Button
ベース
btn_borderless_material.xml
ToggleButton
ベース
ProgressBar
Horizontal
SeekBar
scrubber_control_material_anim.xml
scrubber_progress_horizontal_material.xml
Spinner
ScrollBar
FastScroll
thumb
track
TimePicker のヘッダー
ExpandableListView
selectableItemBackground
item_background_borderless_material.xml
■ 参考
- normal : colorControlNormal
- checked: colorControlActivated
RadioButton
- normal : colorControlNormal
- checked: colorControlActivated
Switch
thumb
- normal : colorSwitchThumbNormal
- checked: colorControlActivated
track
- normal : colorForeground, alpha=0.3
- checked: colorControlActivated, alpha=0.3
RatingBar
- normal : colorControlNormal
- pressed: colorControlActivated
ratingbar_full_filled_material.xml
EditText
- normal : colorControlNormal
- focused: colorControlActivated
Text選択
- ハンドル : colorControlActivated
- カーソル : colorControlActivated
text_select_handle_left_material.xml
text_select_handle_middle_material.xml
text_select_handle_right_material.xml
Button
ベース
- normal : colorButtonNormal
- pressed : colorControlHighlight
btn_borderless_material.xml
ToggleButton
ベース
- normal : colorButtonNormal
- pressed : colorControlHighlight
- normal : colorControlNormal
- checked: colorControlActivated
ProgressBar
- くるくる : colorControlActivated
Horizontal
- ベース : colorControlNormal, alpha=disabledAlpha
- Progress : colorControlActivated
- SecondaryProgress : colorControlActivated, alpha=disabledAlpha
SeekBar
- ベース : colorControlNormal
- Progress : colorControlActivated
- 取手 : colorControlActivated
scrubber_control_material_anim.xml
scrubber_progress_horizontal_material.xml
Spinner
- normal : colorControlNormal
- pressed : colorControlActivated
- checked : colorControlActivated
ScrollBar
- handle : colorControlNormal
FastScroll
thumb
- normal : colorControlNormal
- pressed : colorControlActivated
track
- 常時 : colorControlNormal
TimePicker のヘッダー
- normal : colorAccent
- pressed: colorControlHighlight
ExpandableListView
- expander : colorControlNormal
selectableItemBackground
- pressed: colorControlHighlight
item_background_borderless_material.xml
■ 参考
<style name="Theme.Material">
...
<!-- Color palette -->
<item name="colorPrimaryDark">@color/primary_dark_material_dark</item>
<item name="colorPrimary">@color/primary_material_dark</item>
<item name="colorAccent">@color/accent_material_dark</item>
<item name="colorEdgeEffect">?attr/colorPrimary</item>
<item name="colorControlNormal">?attr/textColorSecondary</item>
<item name="colorControlActivated">?attr/colorAccent</item>
<item name="colorControlHighlight">@color/ripple_material_dark</item>
<item name="colorButtonNormal">@color/btn_default_material_dark</item>
<item name="colorSwitchThumbNormal">@color/switch_thumb_material_dark</item>
</style>
<style name="Theme.Material.Light" parent="Theme.Light">
...
<!-- Color palette -->
<item name="colorPrimaryDark">@color/primary_dark_material_light</item>
<item name="colorPrimary">@color/primary_material_light</item>
<item name="colorAccent">@color/accent_material_light</item>
<item name="colorControlNormal">?attr/textColorSecondary</item>
<item name="colorControlActivated">?attr/colorAccent</item>
<item name="colorControlHighlight">@color/ripple_material_light</item>
<item name="colorButtonNormal">@color/btn_default_material_light</item>
<item name="colorSwitchThumbNormal">@color/switch_thumb_material_light</item>
</style>
- support/v7/appcompat/src/android/support/v7/internal/widget/TintManager.java
- support/v7/appcompat/src/android/support/v7/internal/widget/TintDrawableWrapper.java
2015年1月2日金曜日
Theme.Material の SeekBar は setProgress() で
secondaryProgress の描画が消えてしまう
SeekBar は ProgressBar を継承しているので、setSecondaryProgress() で2番目のプログレスを設定することができます。
下記の動画は setSecondaryProgress() を呼んだ後に setProgress() を呼んだものです。
Holo テーマのスタイルの SeekBar(一番上)では、setProgress() を呼ぶと secondary progress のバーの描画はそのままで progress のバーがセットされます。
一方、Material テーマのスタイルの SeekBar(真ん中)では、setProgress() を呼ぶと secondary progress のバーの描画が消えてしまいます。ちなみにこの時点で getSecondaryProgress() を呼ぶと、描画は消えていますがセットされている値が返ってきます。
Material テーマのスタイルの ProgressBar(一番下)では、secondary progress のバーの描画は消えません。
そこで、SeekBar に style="@android:style/Widget.Material.ProgressBar.Horizontal" を指定してみたところ、Progress Bar と同じような見た目になり、secondary progress のバーの描画は消えなくなりました。
@android:drawable/scrubber_progress_horizontal_material
なぜ selector の中に入れると描画が変になるのかよくわかりませんが、style="@android:style/Widget.Material.ProgressBar.Horizontal" を指定するのが手っ取り早そうです。
下記の動画は setSecondaryProgress() を呼んだ後に setProgress() を呼んだものです。
Holo テーマのスタイルの SeekBar(一番上)では、setProgress() を呼ぶと secondary progress のバーの描画はそのままで progress のバーがセットされます。
一方、Material テーマのスタイルの SeekBar(真ん中)では、setProgress() を呼ぶと secondary progress のバーの描画が消えてしまいます。ちなみにこの時点で getSecondaryProgress() を呼ぶと、描画は消えていますがセットされている値が返ってきます。
Material テーマのスタイルの ProgressBar(一番下)では、secondary progress のバーの描画は消えません。
そこで、SeekBar に style="@android:style/Widget.Material.ProgressBar.Horizontal" を指定してみたところ、Progress Bar と同じような見た目になり、secondary progress のバーの描画は消えなくなりました。
<SeekBar
style="@android:style/Widget.Material.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Widget.Material.ProgressBar.Horizontal は次のようになっており、progressDrawable の指定が作用していると予想しました。
<style name="Widget.Material.ProgressBar.Horizontal" parent="Widget.ProgressBar.Horizontal">
<item name="progressDrawable">@drawable/progress_horizontal_material</item>
<item name="indeterminateDrawable">@drawable/progress_indeterminate_horizontal_material</item>
<item name="minHeight">16dip</item>
<item name="maxHeight">16dip</item>
</style>
そこで、@android:drawable/progress_horizontal_material をプロジェクト内に持ってきて次のように指定したところ、secondary progress のバーの描画は消えなくなりました。
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:progressDrawable="@drawable/progress_horizontal_material" />
progress_horizontal_material.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<nine-patch android:src="@drawable/progress_mtrl_alpha"
android:tint="?attr/colorControlNormal"
android:alpha="?android:attr/disabledAlpha" />
</item>
<item android:id="@android:id/secondaryProgress">
<scale android:scaleWidth="100%">
<nine-patch android:src="@drawable/progress_mtrl_alpha"
android:tint="?attr/colorControlActivated"
android:alpha="?android:attr/disabledAlpha" />
</scale>
</item>
<item android:id="@android:id/progress">
<scale android:scaleWidth="100%">
<nine-patch android:src="@drawable/progress_mtrl_alpha"
android:tint="?android:attr/colorControlActivated" />
</scale>
</item>
</layer-list>
Material テーマの SeekBar のデフォルトスタイルは Widget.Material.SeekBar です。このスタイルでは progressDrawable に @android:drawable/scrubber_progress_horizontal_material が指定されています。
<style name="Widget.Material.SeekBar">
<item name="indeterminateOnly">false</item>
<item name="progressDrawable">@drawable/scrubber_progress_horizontal_material</item>
<item name="indeterminateDrawable">@drawable/scrubber_progress_horizontal_material</item>
<item name="thumb">@drawable/scrubber_control_material_anim</item>
<item name="splitTrack">true</item>
<item name="focusable">true</item>
<item name="paddingStart">16dip</item>
<item name="paddingEnd">16dip</item>
<item name="mirrorForRtl">true</item>
<item name="background">?attr/selectableItemBackgroundBorderless</item>
</style>
scrubber_progress_horizontal_material.xml は progress_horizontal_material.xml と違い、ルートタグが <selector> です。
@android:drawable/scrubber_progress_horizontal_material
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false">
<nine-patch android:src="@drawable/scrubber_track_mtrl_alpha"
android:tint="?attr/colorControlNormal" />
</item>
<item>
<layer-list>
<item android:id="@id/background">
<nine-patch android:src="@drawable/scrubber_track_mtrl_alpha"
android:tint="?attr/colorControlNormal" />
</item>
<item android:id="@id/secondaryProgress">
<scale android:scaleWidth="100%">
<nine-patch android:src="@drawable/scrubber_primary_mtrl_alpha"
android:tint="?attr/colorControlNormal" />
</scale>
</item>
<item android:id="@id/progress">
<scale android:scaleWidth="100%">
<nine-patch android:src="@drawable/scrubber_primary_mtrl_alpha"
android:tint="?attr/colorControlActivated" />
</scale>
</item>
</layer-list>
</item>
</selector>
これの <layer-list> 部分だけを取り出して progressDrawable に指定したところ、secondary progress のバーの描画が消えなくなりました。なぜ selector の中に入れると描画が変になるのかよくわかりませんが、style="@android:style/Widget.Material.ProgressBar.Horizontal" を指定するのが手っ取り早そうです。
登録:
投稿 (Atom)