6

androidコードから名前空間のいくつかのスタイル属性を取得しようとしています。ここに、関連する抜粋を同封します。AttributeSet attrsカスタムに渡されるパラメータですTextView

private static final int[] ATTRS = new int[] { android.R.attr.textSize,
   android.R.attr.text, android.R.attr.textColor,
   android.R.attr.gravity };

private void processAndroidAttributes(final Context context,
   final AttributeSet attrs) {
   final TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);
   try {

       final String text = a.getString(1);
       myTextView.setText(text);
       final float textSize = a.getDimensionPixelSize(0, DEFAULT_TEXT_SIZE);
       myTextView.setTextSize(textSize);
}

私の問題は、 で説明されている 4 つの属性を読み取りたいということですint[] ATTRS。ご覧のとおりtextSize、この配列の最初の要素として配置しました。その理由は単純です。配列の 2 番目の場所に置き換えた場合、その値は正しく読み取られません (代わりに、提供された既定値が読み込まれます)。一方、テキストは配列内のどの位置に配置しても正しくロードされますATTRSgravityとの位置設定を実験する勇気はありませんtextColorが、この順列では機能しません。

属性を取得するという使用可能な動作の理由を誰かが説明できますか?

4

5 に答える 5

12

これは API のバグのようです。gravitytexttextSizeおよびの 4 つの属性についてテストを行いましたtextColor。使用したコードは次のとおりです。

private void processAndroidAttributes(final Context context, final AttributeSet attrs) {
    ATTRS = new Integer[] {
               android.R.attr.textSize, android.R.attr.text,
               android.R.attr.textColor, android.R.attr.gravity };
    Arrays.sort(ATTRS);
    do {
        printPermutation(ATTRS);
        tryApplyingStyles(context, attrs, ATTRS);
        ATTRS = nextPermutation(ATTRS);
    } while ((ATTRS = nextPermutation(ATTRS)) != null);
}

このメソッドprocessAndroidAttributesは、リストされたすべての属性を適用しようとし、それらが適用されたか、またはデフォルトが使用されたかをチェックします。反復ごとに、配列のATTRS内容と、実際の値が使用されたか ( のフラグが付けられている1) またはデフォルトが使用されたか ( のフラグが付けられている) を出力し0ます。上記のコードを実行すると、次のようになります (すべての反復で数行が出力されます)。

[16842901,16842904,16842927,16843087]
1111
[16842901,16842904,16843087,16842927]
1110
[16842901,16842927,16842904,16843087]
1101
[16842901,16842927,16843087,16842904]
1101
[16842901,16843087,16842904,16842927]
1100
[16842901,16843087,16842927,16842904]
1100
[16842904,16842901,16842927,16843087]
1011
[16842904,16842901,16843087,16842927]
1010
[16842904,16842927,16842901,16843087]
1011
[16842904,16842927,16843087,16842901]
1011
[16842904,16843087,16842901,16842927]
1010
[16842904,16843087,16842927,16842901]
1010
[16842927,16842901,16842904,16843087]
1001
[16842927,16842901,16843087,16842904]
1001
[16842927,16842904,16842901,16843087]
1001
[16842927,16842904,16843087,16842901]
1001
[16842927,16843087,16842901,16842904]
1001
[16842927,16843087,16842904,16842901]
1001
[16843087,16842901,16842904,16842927]
1000
[16843087,16842901,16842927,16842904]
1000
[16843087,16842904,16842901,16842927]
1000
[16843087,16842904,16842927,16842901]
1000
[16843087,16842927,16842901,16842904]
1000
[16843087,16842927,16842904,16842901]
1000

ご覧のとおり、これは配列がソートされていることを期待しているかのようで、外れ値がいくつかあるだけです。obtainStyledAttributesのドキュメントでは、属性 ID の順序を期待するように指定されていないため、これは Android API のバグだと思います。

于 2013-09-30T10:58:24.787 に答える
1

誰かが私と同じ結論を出したことに驚いています。順序を気にする必要がないように、obtainStyledAttributes には項目配列を 1 つだけ使用することにしました。

http://androidxref.com/2.2.3/xref/frameworks/base/core/jni/android_util_AssetManager.cpp#911 このソースを詳しく見ていませんでしたが、Android は AttributeSet を昇順で 1 回だけ繰り返すと思います。効率。

于 2013-11-08T01:45:09.917 に答える
1

議論された問題を確認し、今後の参考のために簡単な解決策を追加します。詳細については、他の回答を参照してください。

2 つのことに注意してください。

  1. int[] attrs 配列の値の名前はアルファベット順にソートされます
  2. getsStyledAttributes(AttributeSet, int[], int int) を呼び出します

    public static int[] getCommonStyledAttributes() {
      return new int[] {
        R.attr.bottom, //0
        R.attr.height, //1
        R.attr.layout, //2
        R.attr.left, //3
        R.attr.paddings, //4
        R.attr.right, //5
        R.attr.top, //6
        R.attr.width //7
      };
    }
    
    TypedArray a = context.getTheme().obtainStyledAttributes(paramAttributeSet, getCommonStyledAttributes(), 0, 0);
        this.mWidth = a.getInt(7, 0);
        this.mHeight = a.getInt(1, 0);
        this.left = a.getInt(3, 0);
        this.top = a.getInt(6, 0);
        this.right = a.getInt(5, 0);
        this.bottom = a.getInt(0, 0);
        this.type = a.getInt(2, 0);
        a.recycle();
    
于 2014-03-25T08:23:48.637 に答える