Подтвердить что ты не робот

Как читать атрибут пользовательского измерения из 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 - это именно то, что мне нужно.

4b9b3361

Ответ 1

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

  • сначала вам понадобится строка объявления пространства имен xml в верхней части вашего xml, точно так же, как и с android xmlns: xmlns: foo = "http://schemas.android.com/apk/res- авто"
  • тогда вам нужно префикс 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);

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

Ответ 2

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

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

    // ...
}