Как программно установить атрибут стиля в представлении - PullRequest
95 голосов
/ 07 января 2010

Я получаю представление из XML с кодом ниже:

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

Я хотел бы установить «стиль» для кнопки, как я могу сделать это в Java, так как я хочу использовать несколько стилей для каждой кнопки, которую я буду использовать.

Ответы [ 11 ]

49 голосов
/ 07 января 2010

Как правило, вы не можете изменять стили программно; Вы можете установить внешний вид экрана, или части макета, или отдельной кнопки в макете XML, используя темы или стили . Тем не менее, может применяться программно .

Существует также такая вещь, как StateListDrawable, которая позволяет вам определять различные элементы рисования для каждого состояния, в котором может находиться ваш Button, будь то фокусировка, выделение, нажатие, отключение и т. Д.

Например, чтобы ваша кнопка меняла цвет при нажатии, вы можете определить XML-файл с именем res/drawable/my_button.xml directory следующим образом:

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

40 голосов
/ 30 января 2014

Прежде всего, вам не нужно использовать разметчик для создания простой кнопки. Вы можете просто использовать:

button = new Button(context);

Если вы хотите стилизовать кнопку, у вас есть 2 варианта: самый простой - просто указать все элементы в коде, как предлагают многие другие ответы:

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

Другой вариант - определить стиль в XML и применить его к кнопке. В общем случае вы можете использовать ContextThemeWrapper для этого:

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

Чтобы изменить текстовые атрибуты в TextView (или его подклассах, таких как Button), существует специальный метод:

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

Этот последний нельзя использовать для изменения всех атрибутов; например, чтобы изменить отступы, вы должны использовать ContextThemeWrapper. Но для цвета текста, размера и т. Д. Вы можете использовать setTextAppearance.

14 голосов
/ 23 сентября 2011

Да, вы можете использовать, например, кнопку

Button b = new Button(this);
b.setBackgroundResource(R.drawable.selector_test);
9 голосов
/ 05 декабря 2016

Вы можете сделать атрибуты стиля следующим образом:

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"

    />
6 голосов
/ 16 сентября 2016

Если вы используете библиотеку поддержки, вы можете просто использовать

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

для TextViews и кнопок. Существуют похожие классы для остальных видов: -)

6 голосов
/ 24 марта 2016

Для тех, кто ищет ответ на материал, см. Этот пост SO: Цветовые кнопки в Android с Material Design и AppCompat

Я использовал комбинацию этого ответа, чтобы установить цвет текста по умолчанию:кнопка для белого цвета для моей кнопки: 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_button может быть просто обычной Button или кнопкой 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);
}
5 голосов
/ 04 июня 2013

Ответ @Dayerman и @h_rules правильный. Чтобы дать подробный пример с кодом, В папке drawable создайте XML-файл с именем 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>

Тогда на 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>
3 голосов
/ 16 апреля 2018

В зависимости от того, какие атрибуты стиля вы хотите изменить, вы можете использовать Парижскую библиотеку:

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

Поддерживаются многие атрибуты, такие как background, padding, textSize, textColor и т. Д.

Отказ от ответственности: я создал библиотеку.

3 голосов
/ 14 ноября 2014

Во время выполнения вы знаете, какой стиль вы хотите, чтобы ваша кнопка имела. Поэтому заранее, в 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);

где контейнер - это контейнер ViewGroup, связанный с методом onCreateView, который вы переопределяете при создании фрагмента.

Нужны еще две такие кнопки? Вы создаете их так:

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 голосов
/ 25 мая 2017

Я сделал вспомогательный интерфейс для этого, используя шаблон держателя.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...