2013-05-16 73 views
19

我讓我的自定義組件只是將幾個TextViews放在一起。現在,我希望能夠直接從代碼初始化我的自定義控制,獨立傳遞文本的大小爲每個電視如何從java代碼中讀取自定義維度屬性

我的屬性定義:成分的

<resources> 
    <declare-styleable name="BasicGauge"> 
     <attr name="valueTextSize" format="dimension" /> 
     <attr name="titleTextSize" format="dimension" /> 
     <attr name="unitsTextSize" format="dimension" /> 
    </declare-styleable> 
</resources> 

樣品初始化:

<pl.com.digita.BikeComputerUi.customviews.BasicGauge 
    android:id="@+id/basicGauge1" 
    android:layout_width="0dp" 
    android:layout_height="wrap_content" 
    android:layout_weight="1" 
    android:padding="10dp" 
    valueTextSize="40sp"> 

</pl.com.digita.BikeComputerUi.customviews.BasicGauge> 

如何嘗試讀取組件構造函數中的屬性:

final int N = typedArray.getIndexCount(); 
for (int i = 0; i < N; i++) { 
    int attribute = typedArray.getIndex(i); 
    switch (attribute) { 
     case R.styleable.BasicGauge_valueTextSize: 
      valueTextSize = typedArray.getString(attribute); 
      break; 
     case R.styleable.BasicGauge_titleTextSize: 
      titleTextSize = typedArray.getString(attribute); 
      break; 
     case R.styleable.BasicGauge_unitsTextSize: 
      unitsTextSize = typedArray.getString(attribute); 
      break; 
    } 
    typedArray.recycle(); 
} 

問題: 創建後,我的所有值仍爲空。 40sp正是我期望的價值。

回答

46

有幾件事情說:

  • 首先你需要在你的XML頂部的XML命名空間報關行,正是以同樣的方式,你與Android的xmlns做的領域:xmlns:富=「HTTP ://schemas.android.com/apk/res-auto」
  • ,那麼你需要與你的xmlns前綴valueTextSize:FOO:valueTextSize = 「40SP」

之後,它不是一個很好的主意獲得一個字符串,android提供更強大的解決方案來處理尺寸:

int unitsTextSize = typedArray.getDimensionPixelSize(R.styleable.BasicGauge_unitsTextSize, textSize); 

然後有一些subtilities:

  • 用於油漆,或textpaint,您可以將此值是:paint.setTextSize(unitTextSize):
  • 爲一個TextView,上述方法會失敗,你有使用的setText過載,以獲得正確的結果:textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, unitTextSize);

的差異來自於所謂的「原始像素」(根據密度未縮放,只是原始)和「縮放PI xels「(相反)。

+0

首先 - 感謝您解決我的問題。將維度值傳遞到複合組件內的TextView的最佳方式是什麼? – piotrpo

+0

您這樣做的方式:使用自定義屬性,在構建複合視圖時檢索它,然後在創建或膨脹時將其傳遞給視圖。 – Snicolas

11

對於多一點背景下接受的答案:

attrs.xml

設置與dimension格式的自定義屬性。

<resources> 
    <declare-styleable name="CustomView"> 
     <attr name="valueTextSize" format="dimension" /> 
     <attr name="titleTextSize" format="dimension" /> 
     <attr name="unitsTextSize" format="dimension" /> 
    </declare-styleable> 
</resources> 

activity.xml

參考您與xmlns:app=...屬性,並將它們與app:...你的XML。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       xmlns:app="http://schemas.android.com/apk/res-auto" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent"> 

    <com.example.myproject.CustomView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     app:valueTextSize="40sp" 
     app:titleTextSize="20sp" 
     app:unitsTextSize="24sp" /> 

</RelativeLayout> 

CustomView。java

使用getDimensionPixelSize從TypedArray中獲取值。在您的自定義視圖中,只需使用像素。如果需要轉換爲其他維度,請參閱this answer

public class CustomView extends View { 

    private float mValueTextSize; // pixels 
    private float mTitleTextSize; // pixels 
    private float mUnitsTextSize; // pixels 

    public CustomView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     TypedArray a = context.getTheme().obtainStyledAttributes(
       attrs, R.styleable.CustomView, 0, 0); 
     try { 
      mValueTextSize = a.getDimensionPixelSize(R.styleable.CustomView_valueTextSize, 0); 
      mTitleTextSize = a.getDimensionPixelSize(R.styleable.CustomView_titleTextSize, 0); 
      mUnitsTextSize = a.getDimensionPixelSize(R.styleable.CustomView_unitsTextSize, 0); 
     } finally { 
      a.recycle(); 
     } 
    } 

    // ... 
} 
+0

乾淨整潔。 –

相關問題