私は Android 開発の初心者で、その仕組みを理解するために小さなアプリを書いています。すべてが機能していますが、現時点では、カスタム ドローアブルの状態についてのポイントを得ることができません... サンプル コードで説明させてください。
これが私のattrs.xmlです。ここでは、ブール値である「oddMonth」という名前の属性を宣言しています。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="DayView">
<attr name="oddMonth" format="boolean"/>
</declare-styleable>
</resources>
次に、カスタム ビューがあります。
<?xml version="1.0" encoding="utf-8"?>
<com.example.calendar.DayView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="90dp"
android:background="@drawable/dayview_state" >
<TextView android:id="@+id/day_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:paddingRight="3dp" />
</com.example.calendar.DayView>
そこで、dayview_state.xml ファイルを参照する「android:background="@drawable/dayview_state"」という行を追加します。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:easycalendar="http://schemas.android.com/apk/res/com.example.calendar">
<item easycalendar:oddMonth ="true" android:drawable="@drawable/customborder_odd" />
<item easycalendar:oddMonth ="false" android:drawable="@drawable/customborder_even"/>
</selector>
これまでのところ...私が理解できることは.... attrs.xmlで定義された属性があります。この属性は、カスタム ビューの状態を表します。この属性のブール値によると、私のアプリは 2 つの異なる xml (ここでは重要ではありません) のいずれかをロードし、それぞれが異なるドローアブルを定義します。最後のステップは、カスタム クラスを作成することです。クラスからの抜粋に従います。
public class DayView extends RelativeLayout {
private static final int[] STATE_ODD_MONTH = { R.attr.oddMonth };
private boolean mOddmonth = true;
public DayView(Context mContext, AttributeSet attrs) {
super(mContext, attrs);
}
@Override
protected int[] onCreateDrawableState(int extraSpace) {
if (mOddmonth) {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
mergeDrawableStates(drawableState, STATE_ODD_MONTH);
return drawableState;
} else {
return super.onCreateDrawableState(extraSpace);
}
}
public boolean isOddMonth() {
return mOddmonth;
}
public void setOddMonth(boolean oddMonth) {
if (mOddmonth != oddMonth) {
mOddmonth = oddMonth;
refreshDrawableState();
}
}
}
わかりました...ここにプライベート変数 mOddMonth があり、getter と setter があります。このビューを他の場所でインフレートするために使用されるコンストラクター。別のプライベート変数:
private static final int[] STATE_ODD_MONTH = { R.attr.oddMonth };
これは、1 つの int 値のみで構成される配列であり、attrs.xml で定義された属性 oddMonth への参照です。そして継承されたメソッド:
@Override
protected int[] onCreateDrawableState(int extraSpace) {
if (mOddmonth) {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
mergeDrawableStates(drawableState, STATE_ODD_MONTH);
return drawableState;
} else {
return super.onCreateDrawableState(extraSpace);
}
}
これは本当に「深く」理解することはできません...まあ、ローカル変数mOddMonthがtrueの場合は状態を追加し、そうでない場合は追加しないようです。だから...私のコードは、dayview_state.xmlを次のものに置き換えた場合にのみ機能します。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:easycalendar="http://schemas.android.com/apk/res/com.example.calendar">
<item easycalendar:oddMonth ="true" android:drawable="@drawable/customborder_odd" />
<item android:drawable="@drawable/customborder_even"/>
</selector>
このようにして、状態が存在する場合は最初のレイアウトがロードされ、それ以外の場合は 2 番目のレイアウトがロードされます。しかし、国家の価値についてはどうでしょうか? 私のコードのどこにも、この変数/属性の値を設定していません....どこが間違っていますか?