概要
JavaからKotlinに書き換える中でこの2つのコンストラクタ定義でSpinnerの挙動が異なってはまったのでメモ。
public class CustomSpinner extends AppCompatSpinner {
public CustomSpinner(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public CustomSpinner(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomSpinner(Context context) {
super(context);
}
}
class CustomSpinnerKt @JvmOverloads constructor(
context: Context,
attr: AttributeSet? = null,
defStyleAttr: Int = 0
) : AppCompatSpinner(context, attr, defStyleAttr) {
}
原因
super(context, attrs);
では defStyleAttr に R.attr.spinnerStyle
デフォルトで適応されるのが原因だった。
AppCompatSpinner.java
public AppCompatSpinner(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.spinnerStyle);
}
R.attr.spinnerStyle
の定義を遡っていくとv21以上では Widget.Material.Spinner
を継承している。
Widget.Material.Spinner
<style name="Widget.Material.Spinner" parent="Widget.Spinner.DropDown">
<item name="background">@drawable/spinner_background_material</item>
<item name="dropDownSelector">?attr/listChoiceBackgroundIndicator</item>
<item name="popupBackground">@drawable/popup_background_material</item>
<item name="popupElevation">@dimen/floating_window_z</item>
<item name="popupAnimationStyle">@empty</item>
<item name="popupEnterTransition">@transition/popup_window_enter</item>
<item name="popupExitTransition">@transition/popup_window_exit</item>
<item name="dropDownVerticalOffset">0dip</item>
<item name="dropDownHorizontalOffset">0dip</item>
<item name="overlapAnchor">true</item>
<item name="dropDownWidth">wrap_content</item>
<item name="popupPromptView">@layout/simple_dropdown_hint</item>
<item name="gravity">start|center_vertical</item>
<item name="disableChildrenWhenDisabled">true</item>
</style>
一方、v21未満では Base.Widget.AppCompat.Spinner
を継承している。
Base.Widget.AppCompat.Spinner
<style name="Base.Widget.AppCompat.Spinner" parent="Platform.Widget.AppCompat.Spinner">
<item name="android:background">@drawable/abc_spinner_mtrl_am_alpha</item>
<item name="android:popupBackground">@drawable/abc_popup_background_mtrl_mult</item>
<item name="android:dropDownSelector">?attr/listChoiceBackgroundIndicator</item>
<item name="android:dropDownVerticalOffset">0dip</item>
<item name="android:dropDownHorizontalOffset">0dip</item>
<item name="android:dropDownWidth">wrap_content</item>
<item name="android:clickable">true</item>
<item name="android:gravity">left|start|center_vertical</item>
<item name="overlapAnchor">true</item>
</style>
解決策
defStyleAttr
のデフォルト引数に R.attr.spinnerStyle
を指定した。
class CustomSpinnerKt @JvmOverloads constructor(
context: Context,
attr: AttributeSet? = null,
defStyleAttr: Int = R.attr.spinnerStyle
) : AppCompatSpinner(context, attr, defStyleAttr) {
}