webentwicklung-frage-antwort-db.com.de

Wie programmgesteuert das Stilattribut in einer Ansicht festgelegt wird

Ich bekomme eine Ansicht aus dem XML mit dem folgenden Code: 

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

Ich möchte einen "Stil" für die Schaltfläche festlegen. Wie kann ich das in Java tun, da ich für jede Schaltfläche mehrere Styles verwenden möchte.

87
Lint_

Normalerweise können Sie Stile nicht programmgesteuert ändern. Sie können das Erscheinungsbild eines Bildschirms oder eines Teils eines Layouts oder eine einzelne Schaltfläche in Ihrem XML-Layout mithilfe von Themes oder Styles festlegen. Themes können jedoch programmgesteuert angewendet werden .

Es gibt auch eine StateListDrawable , mit der Sie für jeden Zustand, in dem sich Ihre Button befinden kann, unterschiedliche Drawables definieren können, z. B. fokussiert, ausgewählt, gedrückt, deaktiviert usw.

Wenn Sie beispielsweise möchten, dass Ihre Schaltfläche die Farbe ändert, wenn Sie sie drücken, können Sie eine XML-Datei mit dem Namen res/drawable/my_button.xml-Verzeichnis wie folgt definieren:

<?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>

Sie können diesen Selektor dann auf eine Button anwenden, indem Sie die Eigenschaft Android:background="@drawable/my_button" festlegen.

47
Christopher Orr

Zunächst müssen Sie keinen Layout-Inflator verwenden, um einen einfachen Button zu erstellen. Sie können einfach verwenden:

button = new Button(context);

Wenn Sie die Schaltfläche formatieren möchten, haben Sie zwei Möglichkeiten: Die einfachste ist, alle Elemente im Code anzugeben, wie in vielen anderen Antworten vorgeschlagen:

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

Die andere Option besteht darin, den Stil in XML zu definieren und auf die Schaltfläche anzuwenden. Im allgemeinen Fall können Sie dazu eine ContextThemeWrapper verwenden:

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

Um die textbezogenen Attribute in einer TextView (oder deren Unterklassen wie Button) zu ändern, gibt es eine spezielle Methode:

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

Mit dem letzten können nicht alle Attribute geändert werden. Um beispielsweise die Auffüllung zu ändern, müssen Sie eine ContextThemeWrapper verwenden. Aber für Textfarbe, Größe usw. können Sie setTextAppearance verwenden.

36
beetstra

Ja, Sie können beispielsweise eine Schaltfläche verwenden 

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

Sie können Stilattribute wie folgt ausführen: 

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

anstelle von: 

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

    />
8
Kristy Welsh

Für alle, die nach einer Materialantwort suchen, finden Sie diesen Beitrag SO: Coloring Buttons in Android mit Material Design und AppCompat

Ich habe eine Kombination dieser Antwort verwendet, um die Standardtextfarbe der Schaltfläche für meine Schaltfläche auf Weiß zu setzen: https://stackoverflow.com/a/32238489/3075340

Dann diese Antwort https://stackoverflow.com/a/34355919/3075340 , um die Hintergrundfarbe programmgesteuert einzustellen. Der Code dafür lautet:

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

your_colored_button kann nur eine normale Button- oder eine AppCompat-Schaltfläche sein, wenn Sie möchten - Ich habe den obigen Code mit beiden Arten von Tasten getestet, und er funktioniert.

BEARBEITEN: Ich habe festgestellt, dass Pre-Lollipop-Geräte nicht mit dem obigen Code funktionieren. In diesem Beitrag erfahren Sie, wie Sie Unterstützung für Pre-Lollipop-Geräte hinzufügen: https://stackoverflow.com/a/30277424/3075340

Grundsätzlich tun Sie dies:

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
Micro

Die Antwort von @Dayerman und @h_rules ist richtig. Um ein ausführliches Beispiel mit Code zu geben, Erstellen Sie im Drawable-Ordner eine XML-Datei mit dem Namen button_disabled.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>

Dann in Java,

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

Dadurch wird die Eigenschaft der Schaltfläche deaktiviert und die Farbe auf Silber gesetzt.

[Die Farbe ist in color.xml definiert als:

<resources>

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

</resources>
5
biniam

Zur Laufzeit wissen Sie, welchen Stil Ihre Schaltfläche haben soll. Zuvor können Sie also in xml im Layoutordner alle Schaltflächen mit den gewünschten Stilen bereithalten. Im Layoutordner haben Sie möglicherweise eine Datei mit dem Namen: button_style_1.xml. Der Inhalt dieser Datei könnte folgendermaßen aussehen:

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

Wenn Sie mit Fragmenten arbeiten, blasen Sie in onCreateView diese Schaltfläche auf, beispielsweise:

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

dabei ist container der ViewGroup-Container, der der onCreateView-Methode zugeordnet ist, die Sie beim Erstellen des Fragments überschreiben. 

Benötigen Sie zwei weitere Tasten? Du erschaffst sie so:

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

Sie können diese Schaltflächen anpassen:

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

Dann fügen Sie dem Layout-Container, den Sie in der onCreateView-Methode aufgeblasen haben, Ihre benutzerdefinierten, stilisierten Schaltflächen hinzu:

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

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

Und so können Sie dynamisch mit stilisierten Tasten arbeiten.

3
Jerry Frost

Wenn Sie die Support-Bibliothek verwenden, können Sie einfach verwenden

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

für TextViews und Schaltflächen. Es gibt ähnliche Klassen für den Rest von Views :-)

2
cesards

Abhängig von den Stilattributen, die Sie ändern möchten, können Sie möglicherweise die Pariser Bibliothek verwenden:

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

Viele Attribute wie Hintergrund, Auffüllen, TextSize, TextColor usw. werden unterstützt.

Haftungsausschluss: Ich habe die Bibliothek verfasst.

2
Nathanael

Ich war kürzlich mit demselben Problem konfrontiert. So habe ich es gelöst.

<?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>
  • Ich habe ein LinearLayout mit Android verwendet: weightSum = "2" 
  • Ich gab den beiden untergeordneten Elementen Android: layout_weight = "1" (Ich gab jeweils 50% des übergeordneten Speicherplatzes (Breite und Höhe))
  • Und schließlich gab ich den beiden untergeordneten Elementen verschiedene Hintergrundfarben, um den endgültigen Effekt zu erzielen.

Vielen Dank !

0
steve111MV

Ich habe dazu ein Helfer-Interface mit dem Haltemuster erstellt.

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

Für jeden Stil, den Sie pragmatisch verwenden möchten, implementieren Sie einfach die Schnittstelle, zum Beispiel:

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

Deklarieren Sie ein Stylable in Ihrem attrs.xml. Das Stylable für dieses Beispiel lautet:

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

Hier ist der in styles.xml deklarierte Stil:

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

Und schließlich die Umsetzung des Stylehalters:

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

Ich fand das sehr hilfreich, da es einfach wiederverwendet werden kann und den Code sauber und wortreich hält. Ich würde empfehlen, dies nur als lokale Variable zu verwenden, damit der Garbage Collector seine Arbeit erledigen kann, sobald wir alle Stile eingestellt haben .

0
Kostyantin2216