プログラムでビューのスタイル属性を設定する方法


107

以下のコードを使用して、XMLからビューを取得しています。

Button view = (Button) LayoutInflater.from(this).inflate(R.layout.section_button, null);

ボタンの「スタイル」を設定したいのですが、使用するボタンごとにいくつかのスタイルを使用したいので、Javaでそれを行うにはどうすればよいですか。

回答:


52

通常、プログラムでスタイルを変更することはできません。テーマやスタイルを使用して、画面の外観、レイアウトの一部、またはXMLレイアウトの個々のボタンを設定できます。ただし、テーマはプログラムで適用できます。

フォーカスされている、選択されている、押されている、無効にされているなどStateListDrawable、自分Buttonがいる状態ごとに異なるドローアブルを定義できるようなものもあります。

たとえば、ボタンが押されたときにボタンの色を変更するには、次のres/drawable/my_button.xmlようにdirectory というXMLファイルを定義します。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item
    android:state_pressed="true"
    android:drawable="@drawable/btn_pressed" />
  <item
    android:state_pressed="false"
    android:drawable="@drawable/btn_normal" />
</selector>

次にButton、プロパティを設定して、このセレクターをに適用できますandroid:background="@drawable/my_button"


4
私の問題は、ボタン情報を説明するWebサービスからデータをロードすることです。ボタンは、それらが属するカテゴリに基づいて異なるスタイルを持つ必要があります。そのため、スタイルを動的に設定したいと思います。
Lint_ 2010年

3
Android style属性を変更することはできませんが、Button他のビューと同じようにプログラムで背景を設定できます。また、をButton継承しているためTextView、テキストのプロパティを変更できます。ただ、これらの項目のためのAPIドキュメントを見て... developer.android.com/reference/android/view/...
クリストファー・オア

新しい答えがあるかどうかを確認する直前に、そうすることを考えていました。どうもありがとう。
Lint_ 2010年

5
テキストのサイズ、マージンなどを定義するボタンのスタイルを作成し、それをプログラムでボタンに適用することはできませんか?確かに、同じスタイルにしたいボタンが6つあるとしたら、それは可能でしょうか。
2012年

どの属性を膨張させることができますか?マージン、パディングを膨らませることはできますか?
アンドロイドマン

49

まず、シンプルなボタンを作成するためにレイアウトインフレーターを使用する必要はありません。あなたはただ使うことができます:

button = new Button(context);

ボタンのスタイルを設定する場合、2つの選択肢があります。最も簡単な方法は、他の多くの回答が示唆するように、コード内のすべての要素を指定することです。

button.setTextColor(Color.RED);
button.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);

もう1つのオプションは、スタイルをXMLで定義し、ボタンに適用することです。一般的なケースではContextThemeWrapper、これにa を使用できます。

ContextThemeWrapper newContext = new ContextThemeWrapper(baseContext, R.style.MyStyle);
button = new Button(newContext);

TextView(またはButtonのようなそのサブクラス)のテキスト関連の属性を変更するには、特別なメソッドがあります。

button.setTextAppearance(context, R.style.MyTextStyle);

最後の1つを使用してすべての属性を変更することはできません。たとえば、パディングを変更するには、を使用する必要がありますContextThemeWrapper。ただし、テキストの色、サイズなどは使用できますsetTextAppearance


1
ただ素晴らしい。ContextThemeWrapper-私がずっと探していたものです。
Ayaz Alifov 2016年

これは素晴らしく機能します。しばらくの間、このソリューションを探していました。
jasonjwwilliams 2018年

14

はい、例えばボタンで使用できます

Button b = new Button(this);
b.setBackgroundResource(R.drawable.selector_test);

5
これは背景を設定しますが、スタイルは背景だけでなくそれ以外のものも指定できます。多くのビュー(Buttonを含む)には、スタイルIDをパラメーターとして取るコンストラクターがあるようです。しかし、私はそれをうまく機能させるのに問題があります-ボタンは境界線や何もないテキストとして表示されます。代わりに、ボタンを1つだけ含むレイアウトを(スタイルを指定して)作成し、そのレイアウトを膨らませてから、ボタンのテキストとその他を設定します。
spaaarky21 2013年

11

次のようにスタイル属性を実行できます。

Button myButton = new Button(this, null,android.R.attr.buttonBarButtonStyle);

代わりに:

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/btn"
    style="?android:attr/buttonBarButtonStyle"

    />

7
ボタンを考慮した良い答えが作成されます。既存のボタンに対してそれを行う方法を見るとよいでしょう。
品質の触媒

cesardsからの回答をご覧ください。
Kristy Welsh

10

サポートライブラリを使用している場合は、

TextViewCompat.setTextAppearance(textView, R.style.AppTheme_TextStyle_ButtonDefault_Whatever);

TextViewおよびボタン用。残りのビューにも同様のクラスがあります:-)


このスタイルを取得するには、どのRパッケージを使用する必要がありますか?
htafoya

6

Material Answerをお探しの方は、このSO投稿を参照してください:Material DesignとAppCompatを使用したAndroidのボタンのカラーリング

この回答の組み合わせを使用して、ボタンのデフォルトのテキストの色をボタンの白に設定しました:https : //stackoverflow.com/a/32238489/3075340

次に、この答えhttps://stackoverflow.com/a/34355919/3075340を使用して、プログラムで背景色を設定します。そのためのコードは次のとおりです。

ViewCompat.setBackgroundTintList(your_colored_button,
 ContextCompat.getColorStateList(getContext(),R.color.your_custom_color));

your_colored_buttonButton必要に応じて、通常のボタンまたはAppCompatボタンにすることができます。上記のコードを両方のタイプのボタンでテストしましたが、機能します。

編集:私は、ロリポップ前のデバイスが上記のコードで動作しないことを発見しました。ロリポップ前のデバイスのサポートを追加する方法については、この投稿を参照してください:https : //stackoverflow.com/a/30277424/3075340

基本的にこれを行います:

Button b = (Button) findViewById(R.id.button);
ColorStateList c = ContextCompat.getColorStateList(mContext, R.color.your_custom_color;
Drawable d = b.getBackground();
if (b instanceof AppCompatButton) {
    // appcompat button replaces tint of its drawable background
    ((AppCompatButton)b).setSupportBackgroundTintList(c);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    // Lollipop button replaces tint of its drawable background
    // however it is not equal to d.setTintList(c)
    b.setBackgroundTintList(c);
} else {
    // this should only happen if 
    // * manually creating a Button instead of AppCompatButton
    // * LayoutInflater did not translate a Button to AppCompatButton
    d = DrawableCompat.wrap(d);
    DrawableCompat.setTintList(d, c);
    b.setBackgroundDrawable(d);
}

6

変更するスタイル属性に応じて、Parisライブラリを使用できる場合があります。

Button view = (Button) LayoutInflater.from(this).inflate(R.layout.section_button, null);
Paris.style(view).apply(R.style.YourStyle);

背景、パディング、textSize、textColorなどの多くの属性がサポートされています。

免責事項:私はライブラリを作成しました。


5

@Dayermanと@h_rulesの答えは正しいです。コードで詳細な例を示すには、ドローアブルフォルダーで、button_disabled.xmlというxmlファイルを作成します。

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" android:padding="10dp">   
 <solid android:color="@color/silver"/>
<corners
   android:bottomRightRadius="20dp"
   android:bottomLeftRadius="20dp"
   android:topLeftRadius="20dp"
   android:topRightRadius="20dp"/>
</shape>

次にJavaで

((Button) findViewById(R.id.my_button)).setEnabled(false);
((Button) findViewById(R.id.my_button)).setBackgroundResource(R.drawable.button_disabled);

これにより、ボタンのプロパティが無効に設定され、色がシルバーに設定されます。

[色はcolor.xmlで次のように定義されています:

<resources>

    <color name="silver">#C0C0C0</color>

</resources>

4
@Pacerier:質問はそれをまったく言いません。スタイルがXMLかJavaかはあいまいです。プログラムでスタイルを設定する方法を尋ねるだけです。
Harvey

3

実行時に、ボタンのスタイルを知っています。そのため、事前に、レイアウトフォルダーのxmlで、必要なスタイルのボタンをすべて準備することができます。したがって、レイアウトフォルダーには、button_style_1.xmlという名前のファイルがある場合があります。そのファイルの内容は次のようになります。

<?xml version="1.0" encoding="utf-8"?>
<Button
    android:id="@+id/styleOneButton"
    style="@style/FirstStyle" />

フラグメントを使用している場合は、onCreateViewで次のようにそのボタンを膨らませます。

Button firstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);

ここで、containerは、フラグメントの作成時にオーバーライドするonCreateViewメソッドに関連付けられたViewGroupコンテナーです。

そのようなボタンがさらに2つ必要ですか?あなたはこのようにそれらを作成します:

Button secondFirstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);
Button thirdFirstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);

これらのボタンをカスタマイズできます。

secondFirstStyleBtn.setText("My Second");
thirdFirstStyleBtn.setText("My Third");

次に、カスタマイズした定型化されたボタンを、onCreateViewメソッドでインフレートしたレイアウトコンテナーに追加します。

_stylizedButtonsContainer = (LinearLayout) rootView.findViewById(R.id.stylizedButtonsContainer);

_stylizedButtonsContainer.addView(firstStyleBtn);
_stylizedButtonsContainer.addView(secondFirstStyleBtn);
_stylizedButtonsContainer.addView(thirdFirstStyleBtn);

そして、それが様式化されたボタンを動的に操作する方法です。


0

ホルダーパターンを使用して、このためのヘルパーインターフェイスを作成しました。

public interface StyleHolder<V extends View> {
    void applyStyle(V view);
}

次に、実用的に使用したいすべてのスタイルについて、インターフェースを実装するだけです。次に例を示します。

public class ButtonStyleHolder implements StyleHolder<Button> {

    private final Drawable background;
    private final ColorStateList textColor;
    private final int textSize;

    public ButtonStyleHolder(Context context) {
        TypedArray ta = context.obtainStyledAttributes(R.style.button, R.styleable.ButtonStyleHolder);

        Resources resources = context.getResources();

        background = ta.getDrawable(ta.getIndex(R.styleable.ButtonStyleHolder_android_background));

        textColor = ta.getColorStateList(ta.getIndex(R.styleable.ButtonStyleHolder_android_textColor));

        textSize = ta.getDimensionPixelSize(
                ta.getIndex(R.styleable.ButtonStyleHolder_android_textSize),
                resources.getDimensionPixelSize(R.dimen.standard_text_size)
        );

        // Don't forget to recycle!
        ta.recycle();
    }

    @Override
    public void applyStyle(Button btn) {
        btn.setBackground(background);
        btn.setTextColor(textColor);
        btn.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
    }
}

でスタイル可能要素を宣言しますattrs.xml。この例のスタイル可能範囲は次のとおりです。

<declare-styleable name="ButtonStyleHolder">
    <attr name="android:background" />
    <attr name="android:textSize" />
    <attr name="android:textColor" />
</declare-styleable>

で宣言されたスタイルはstyles.xml次のとおりです。

<style name="button">
    <item name="android:background">@drawable/button</item>
    <item name="android:textColor">@color/light_text_color</item>
    <item name="android:textSize">@dimen/standard_text_size</item>
</style>

そして最後にスタイルホルダーの実装:

Button btn = new Button(context);    
StyleHolder<Button> styleHolder = new ButtonStyleHolder(context);
styleHolder.applyStyle(btn);

これは簡単に再利用でき、コードをクリーンで冗長に保つので非常に便利です。すべてのスタイルの設定が完了したら、ガベージコレクターがそのジョブを実行できるように、ローカル変数としてのみ使用することをお勧めします。


-1

最近同じ問題に直面しました。ここで私はそれを解決した方法です。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

    <!-- This is the special two colors background START , after this LinearLayout, you can add all view that have it for main background-->
    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    android:weightSum="2"

    android:background="#FFFFFF"
    android:orientation="horizontal"
    >

    <View
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="#0000FF" />

    <View
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="#F000F0" />
    </LinearLayout>
    <!-- This is the special two colors background END-->

   <TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:gravity="center"
    android:text="This Text is centered with a special backgound,
    You can add as much elements as you want as child of this RelativeLayout"
    android:textColor="#FFFFFF"
    android:textSize="20sp" />
</RelativeLayout>
  • android:weightSum = "2"でLinearLayoutを使用しました
  • 2つの子要素android:layout_weight = "1"を指定しました(親スペース(幅と高さ)のそれぞれ50%を指定しました)
  • そして最後に、2つの子要素に異なる背景色を与えて、最終的な効果を得ました。

よろしくお願いします!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.