web-dev-qa-db-ja.com

styles.xmlからプログラムでスタイル属性を取得する方法

現在、WebViewまたはTextViewのいずれかを使用して、アプリの1つでWebサービスからの動的データを表示しています。データに純粋なテキストが含まれる場合、TextViewを使用して、styles.xmlからスタイルを適用します。データにHTML(主にテキストと画像)が含まれる場合、WebViewを使用します。

ただし、このWebViewはスタイルがありません。そのため、通常のTextViewとは大きく異なります。 HTMLをデータに直接挿入するだけで、WebViewのテキストのスタイルを設定できることを読みました。これは十分簡単に​​聞こえますが、Styles.xmlのデータをこのHTMLで必要な値として使用したいので、スタイルを変更しても2つの場所で色などを変更する必要はありません。

それで、どうすればこれを行うことができますか?広範な検索を実行しましたが、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に興味があります。

70

プログラムで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()
156
Ole

@Oleが与えた答えは、shadowColor、shadowDx、shadowDy、shadowRadiusなどの特定の属性を使用すると壊れているようです(これらは私が見つけた少数であり、もっとあるかもしれません)

なぜこの問題が発生するのか私にはわからない、私は here について尋ねているが、 @ 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);

この方法を使用する利点は、インデックスではなく名前で値を取得することです。

43
PrivatMamtora

OleとPrivatMamtoraからの回答は私にはうまくいきませんでしたが、これはうまくいきました。

このスタイルをプログラムで読みたいとしましょう:

<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

0
monkey