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

Как получить атрибуты стиля программно из styles.xml

В настоящее время я использую WebView или TextView для отображения некоторых динамических данных, поступающих из веб-службы в одном из моих приложений. Если данные содержат чистый текст, он использует TextView и применяет стиль из styles.xml. Если данные содержат HTML (в основном текст и изображения), он использует WebView.

Однако этот WebView не используется. Поэтому он сильно отличается от обычного TextView. Я читал, что можно стилизовать текст в WebView, просто вставив некоторый HTML непосредственно в данные. Это звучит достаточно просто, но я хотел бы использовать данные из моего Styles.xml в качестве значений, требуемых в этом HTML, поэтому мне не нужно менять цвета и так далее в двух местах, если я изменю свои стили.

Итак, как я смогу это сделать? Я провел несколько расширенных поисков, но не нашел способа получить различные атрибуты стиля из ваших styles.xml. Я что-то пропустил здесь или действительно невозможно получить эти значения?

Стиль, с которого я пытаюсь получить данные, выглядит следующим образом:

<style name="font4">
    <item name="android:layout_width">fill_parent</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:textSize">14sp</item>
    <item name="android:textColor">#E3691B</item>
    <item name="android:paddingLeft">5dp</item>
    <item name="android:paddingRight">10dp</item>
    <item name="android:layout_marginTop">10dp</item>
    <item name="android:textStyle">bold</item>
</style>

В основном меня интересуют textSize и textColor.

4b9b3361

Ответ 1

Можно запрограммировать выбор пользовательских стилей из styles.xml.

Определите произвольный стиль в styles.xml:

<style name="MyCustomStyle">
    <item name="android:textColor">#efefef</item>
    <item name="android:background">#ffffff</item>
    <item name="android:text">This is my text</item>
</style>

Теперь извлеките стили, подобные этому

// The attributes you want retrieved
int[] attrs = {android.R.attr.textColor, android.R.attr.background, android.R.attr.text};

// Parse MyCustomStyle, using Context.obtainStyledAttributes()
TypedArray ta = obtainStyledAttributes(R.style.MyCustomStyle, attrs);

// Fetch the text from your style like this.     
String text = ta.getString(2);

// Fetching the colors defined in your style
int textColor = ta.getColor(0, Color.BLACK);
int backgroundColor = ta.getColor(1, Color.BLACK);

// Do some logging to see if we have retrieved correct values
Log.i("Retrieved text:", text);
Log.i("Retrieved textColor as hex:", Integer.toHexString(textColor));
Log.i("Retrieved background as hex:", Integer.toHexString(backgroundColor));

// OH, and don't forget to recycle the TypedArray
ta.recycle()

Ответ 2

Ответ @Ole, по-видимому, прерывается при использовании определенных атрибутов, таких как shadowColor, shadowDx, shadowDy, shadowRadius (это всего лишь несколько, которые я нашел, может быть больше)

Я не знаю, как почему эта проблема возникает, о которой я спрашиваю о здесь, но @AntoineMarques стиль кодирования, похоже, решает проблему.

Чтобы сделать эту работу с любым атрибутом, это будет что-то вроде этого


Во-первых, определите стиль, который должен содержать идентификаторы ресурса, такие как

attrs.xml

<resources>     
    <declare-styleable name="MyStyle" >
        <attr name="android:textColor" />
        <attr name="android:background" />
        <attr name="android:text" />
    </declare-styleable>
</resources>

Затем в коде вы сделаете это, чтобы получить текст.

TypedArray ta = obtainStyledAttributes(R.style.MyCustomStyle, R.styleable.MyStyle);  
String text = ta.getString(R.styleable.MyStyle_android_text);

Преимущество использования этого метода заключается в том, что вы извлекаете значение по имени, а не по индексу.

Ответ 3

Ответы от Оле и ПриватМамтора не спомогли мне, но это сработало.

Допустим, я хотел зачитать этот стиль:

<style name="Footnote">
    <item name="android:fontFamily">@font/some_font</item>
    <item name="android:textSize">14sp</item>
    <item name="android:textColor">@color/black</item>
</style>

Я мог бы сделать это так:

fun getTextColorSizeAndFontFromStyle(
    context: Context, 
    textAppearanceResource: Int // Can be any style in styles.xml like R.style.Footnote
) {
    val typedArray = context.obtainStyledAttributes(
        textAppearanceResource,
        R.styleable.TextAppearance // These are added to your project automatically.
    )
    val textColor = typedArray.getColorStateList(
        R.styleable.TextAppearance_android_textColor
    )
    val textSize = typedArray.getDimensionPixelSize(
        R.styleable.TextAppearance_android_textSize
    )

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val typeface = typedArray.getFont(R.styleable.TextAppearance_android_fontFamily)

        // Do something with the typeface...

    } else {
        val fontFamily = typedArray.getString(R.styleable.TextAppearance_fontFamily)
            ?: when (typedArray.getInt(R.styleable.TextAppearance_android_typeface, 0)) {
                1 -> "sans"
                2 -> "serif"
                3 -> "monospace"
                else -> null
            }

        // Do something with the fontFamily...
    }
    typedArray.recycle()
}

У меня появилось вдохновение в классе Android TextAppearanceSpan, вы можете найти его здесь: https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/text/style/TextAppearanceSpan.java

Ответ 4

Если принятое решение не работает для попытки переименовать attr.xml в attrs.xml(работал у меня)