右側にチェックボックスを作成しようとして、Android のコードを見ていました。しかし、Androidがチェックボックスアイコン/ドローアブルの幅を測定している場所に戸惑いました。
CheckboxはCompoundButtonクラスを拡張し、onPopulateAccessibilityEvent メソッドのみをオーバーライドします。CompoundButton クラスにはもう少しコード (100 行) があり、Buttonクラスを拡張します。ボタン クラスには余分なコードはほとんどなく、TextViewクラスを拡張します。TextView クラスには、最大量のコード (10,000 行) があります。
ソースコードへのリンクはこちら
CompoundButton Web -構文の強調表示 http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.3_r1/android/widget/CompoundButton.java?av=f
TextView Web - 構文の強調表示 http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.3_r1/android/widget/TextView.java?av=f
TextView には複合ドローアブルと呼ばれる機能があり、テキストの左、右、下、または上にドローアブルを配置できます。だから私はこれが複合ボタンが左側の複合ドローアブルのチェックボックスドローアブルを設定している場所であると仮定しました。しかし、CompoundButton コードでは、これを見つけることができませんでした。
ただし、CompoundButton を拡張してカスタム クラスを作成し、getCompoundPaddingLeft() を呼び出すと、幅がチェックボックスのサイズとほぼ同じになりました。しかし、getCompoundDrawables() を実行すると、onDraw() の時点でも結果は null の配列になります。textView では、すべてのディメンション データを保持する変数はプライベートであるため、CompoundButton がこれらの値をどのように設定しているかわかりません。これは、 TextViewのgetCompoundPaddingLeft()の例です。
public int getCompoundPaddingLeft() {
final Drawables dr = mDrawables;
if (dr == null || dr.mDrawableLeft == null) {
return mPaddingLeft;
} else {
return mPaddingLeft + dr.mDrawablePadding + dr.mDrawableSizeLeft;
}
}
チェックボックスのドローアブルが設定されている CompoundButton のコードは次のとおりです。左にドローアブル画像があることを TextView に渡す方法はないようです。
public void setButtonDrawable(Drawable d) {
if (d != null) {
if (mButtonDrawable != null) {
mButtonDrawable.setCallback(null);
unscheduleDrawable(mButtonDrawable);
}
d.setCallback(this);
d.setState(getDrawableState());
d.setVisible(getVisibility() == VISIBLE, false);
mButtonDrawable = d;
mButtonDrawable.setState(null);
setMinHeight(mButtonDrawable.getIntrinsicHeight());
}
refreshDrawableState();
}
私の質問は、CompoundButton が左側のコンパウンド ドローアブルの幅をどのように設定しているのかということです。すでにチェックボックスを持っているので、右側にチェックボックスを配置するハックには興味がないことに注意してください。
さらに検査すると
textview クラスを拡張してカスタムの textview クラスを作成し、それをカスタムの CompoundButton クラスに拡張させて、いくつかのメソッドをオーバーライドして、チェックボックスの間隔が作成されている場所を特定しようとしました。
チェックボックスのスペースを作成していたのは、compoundLeft ではなく paddingLeft でした。setPadding() メソッドをオーバーライドしたときと同様に、paddingLeft が送信されていました。これは、チェックボックスにパディングなしで背景を配置したかのように意味があり、チェックボックスは描画されません。
パディングは、textView コンストラクター コードのデフォルト スタイルから読み取られています。
a = theme.obtainStyledAttributes( attrs, com.android.internal.R.styleable.TextView, defStyle, 0);
int n = a.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = a.getIndex(i);
switch (attr) {
case com.android.internal.R.styleable.TextView_editable:
editable = a.getBoolean(attr, editable);
break;
.............
使用されている com.android.internal.R.styleable にアクセスできないため、さらに調べる方法がわかりません。