90

現在、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に興味があります。

4

6 に答える 6

191

プログラムでカスタムスタイルを取得することができます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()
于 2012-12-19T12:55:19.903 に答える
55

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

この問題が発生する理由はわかりませんが、ここで質問していますが、 @AntoineMarquesコーディングスタイルで問題が解決したようです。

これを任意の属性で機能させるには、次のようになります。


まず、次のようなリソースIDを含むスタイラブルを定義します。

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

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

于 2014-08-22T23:49:06.013 に答える
3

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

于 2019-02-04T18:08:58.590 に答える
2

以前のソリューションを機能させることができませんでした。

私のスタイルは:

<style name="Widget.TextView.NumPadKey.Klondike" parent="Widget.TextView.NumPadKey">
    <item name="android:textSize">12sp</item>
    <item name="android:fontFamily">sans-serif</item>
    <item name="android:textColor">?attr/wallpaperTextColorSecondary</item>
    <item name="android:paddingBottom">0dp</item>
</style>

android.R.attr.textSizeのgetStyledAttributes()は、「12sp」の文字列結果を提供します。これを解析する必要があります。android.R.attr.textColorの場合、リソースファイルにXML名を付けました。これはあまりにも面倒でした。

代わりに、ContextThemeWrapperを使用する簡単な方法を見つけました。

TextView sample = new TextView(new ContextThemeWrapper(getContext(), R.style.Widget_TextView_NumPadKey_Klondike), null, 0);

これにより、必要なものをクエリするためのフルスタイルのTextViewが得られました。例えば:

float textSize = sample.getTextSize();
于 2021-11-03T17:01:29.677 に答える
0

Kotlinでは、アプリ/ライブラリにandroidx.core:core-ktxライブラリを含めると...

implementation("androidx.core:core-ktx:1.6.0") // Note the -ktx

...次のいずれかを使用できます(TypedArrayをリサイクルする必要はありません)。

// Your desired attribute IDs
val attributes = intArrayOf(R.attr.myAttr1, R.attr.myAttr2, android.R.attr.text)

context.withStyledAttributes(R.style.MyStyle, attributes) {
    val intExample = getInt(R.styleable.MyIntAttrName, 0)
    val floatExample = getFloat(R.styleable.MyFloatAttrName, 0f)
    val enumExample = R.styleable.MyEnumAttrName, MyEnum.ENUM_1 // See Note 1 below
    // Similarly, getColor(), getBoolean(), etc.
}
context.withStyledAttributes(R.style.MyStyle, R.styleable.MyStyleable) {
    // Like above
}
// attributeSet is provided to you like in the constructor of a custom view
context.withStyledAttributes(attributeSet, R.styleable.MyStyleable) {
    // Like above
}

注1(この回答に感謝します)

列挙値を取得するには、次の拡張関数を定義できます。

internal inline fun <reified T : Enum<T>> TypedArray.getEnum(index: Int, default: T) =
    getInt(index, -1).let { if (it >= 0) enumValues<T>()[it] else default }

注2

androidx.core:coreandroidx.core:core-ktxのような-ktx依存関係の違いは、-ktxバリアントにKotlinの便利な拡張関数が含まれていることです。それ以外は同じです。

また、 Oleの回答に感謝します。

于 2021-08-16T12:43:32.340 に答える
-4

受け入れられたソリューションが機能しない場合は、attr.xmlの名前をattrs.xmlに変更してみてください(私のために機能しました)

于 2016-03-10T12:21:55.443 に答える