Как читать атрибут пользовательского измерения из java-кода

Я создал свой собственный компонент, просто добавив несколько TextView вместе. Теперь я хочу, чтобы иметь возможность запускать собственный пользовательский элемент управления непосредственно из кода, передавая размеры текста независимо для каждого из телевизоров

Определение моих атрибутов:

<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 – это именно то, что мне нужно .

Solutions Collecting From Web of "Как читать атрибут пользовательского измерения из java-кода"

Несколько вещей, чтобы сказать:

  • Сначала вам понадобится строка объявления пространства имен xml в верхней части вашего xml точно так же, как и с android xmlns: xmlns: foo = "http://schemas.android.com/apk/res-auto&quot;
  • То вам нужно префикс valueTextSize с помощью xmlns: foo: valueTextSize = "40sp"

После этого не очень хорошая идея получить строку, android предлагает более мощное решение для обработки размеров:

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

То есть некоторые утилит:

  • Для краски или текстовой ссылки вы можете использовать это значение как есть: paint.setTextSize(unitTextSize):
  • Для текстового представления вышеупомянутый подход завершился неудачно, и вы должны использовать перегрузку setText для получения правильного результата: textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, unitTextSize);

Разница исходит из так называемых «сырых пикселей» (немасштабированных по плотности, только сырой) и «масштабированных пикселей» (наоборот).

Для немного большего контекста к принятому ответу:

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=... и установите их в свой xml с помощью app:...

 <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

Получите значения из TypedArray, используя getDimensionPixelSize . В вашем пользовательском представлении просто работайте с пикселями. См. Этот ответ, если вам нужно преобразовать в другое измерение.

 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(); } } // ... }