Программная установка стиля для TextView

Я пытаюсь использовать конструктор TextView в таком стиле:

TextView myText = new TextView(MyActivity.this, null, R.style.my_style);

Однако, когда я это делаю, текстовое представление, похоже, не принимает стиль (я проверил стиль, установив его для статического объекта).

Я тоже пробовал использовать myText.setTextAppearance(MyActivity.this, R.style.my_style), но он тоже не работает.


person Ben    schedule 29.06.2010    source источник


Ответы (11)


Я не верю, что вы можете установить стиль программно. Чтобы обойти это, вы можете создать XML-файл макета шаблона с назначенным стилем, например, в res / layout create tvtemplate.xml как со следующим содержимым:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="This is a template"
        style="@style/my_style" />

затем надуйте это, чтобы создать экземпляр вашего нового TextView:

TextView myText = (TextView)getLayoutInflater().inflate(R.layout.tvtemplate, null);

Надеюсь это поможет.

person Dan Kilpatrick    schedule 30.03.2011
comment
Чем это побеждает ответ Дандре Эллисон, так это тем, что для этого не требуется API v11. - person Martin Capodici; 21.06.2014
comment
Возможно, это сработало, но в этом нет смысла. Как это можно установить с помощью файла xml? если не программно. Есть причины не использовать файлы xml, одна из них - я привык писать код для создания пользовательского интерфейса, поэтому я не хочу изучать новый способ сделать это, поскольку моя память ограничена, и я хочу оставить место для другие вещи. - person Iharob Al Asimi; 12.08.2015
comment
@IharobAlAsimi, верно, все можно делать программно, а LayoutInflater знает все о превращении XML в объекты. К сожалению, многие такие вещи скрыты в частных API-интерфейсах, и единственный способ создать некоторые объекты - предоставить конструктору AttributeSet. - person Miha_x64; 21.04.2017
comment
В отличие от всех других ответов, это действительно сработало со спиннерами, так что это золотая звезда для вас - person Rowan Berry; 19.12.2019
comment
Только это решение работает со всеми атрибутами, определенными в моем стиле, в отличие от решения с конструктором с 4 аргументами (например, textAppearance определен как стиль). - person Myroslav Kolodii; 07.10.2020

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

textView.setTextAppearance(this, R.style.MyTextStyle);

Изменить: это относится к контексту

person Shahul3D    schedule 05.10.2012
comment
Ваш ответ работает, пока все, что вы делаете, - это обезьяна со стилем текста. Это не сработает, если вы пытаетесь делать другие вещи с TextView, например добавлять отступы или поля. Итак, я не говорю, что вы ошибаетесь, но ваш ответ ограничен. Расширение представления во время выполнения - единственный способ применить всеобъемлющий стиль. - person Bill Mote; 05.02.2013
comment
Оба решения - использование раздутого шаблона и использование setTextAppearance - разумны. Чтобы решить проблему заполнения / полей для второго решения, вы можете вызвать textView.setLayoutParams (layoutParams) - person AlanKley; 14.11.2013
comment
Этот метод объявлен устаревшим на уровне API 23. Используйте вместо него setTextAppearance (int) в API 23+. - person Sergii; 28.11.2015
comment
Убедитесь, что версия не ниже API 23 (M). - person Br0thazS0ul; 21.04.2016
comment
используйте метод из библиотеки поддержки, TextViewCompat.setTextAppearance - person Rubin Yoo; 02.12.2016

Вы можете передать ContextThemeWrapper в конструктор следующим образом:

TextView myText = new TextView(new ContextThemeWrapper(MyActivity.this, R.style.my_style));
person maxcanna    schedule 03.07.2013
comment
отличный материал! единственный способ, которым я мог устанавливать стили программно, поддерживая API 8. - person tbraun; 23.11.2013
comment
По какой-то причине это не влияет на стиль моей кнопки. Я определил свой стиль как: <style name="TabButton"><item name="android:background">@drawable/tabbar_button_bkgnd</item>...</style>. А затем вызываю его конструкцией: new Button(new ContextThemeWrapper(context, R.style.TabButton));. Но кнопка просто игнорирует мои настройки. Я здесь что-то не так делаю? - person Aleks N.; 06.01.2014
comment
@ AlaksiejN. Вы должны унаследовать от Widget.Button стиль, подобный этому parent="@android:style/Widget.Button" - person maxcanna; 06.01.2014
comment
@maxcanna По какой-то причине добавление parent ни капли не изменилось. Поэтому я просто выбрал inflate решение. - person Aleks N.; 06.01.2014
comment
@AliakseiN. Вам нужно использовать конструктор с 3 аргументами, например new Button(new ContextThemeWrapper(context, R.style.TabButton), null, 0). В противном случае будет применен стиль кнопки по умолчанию, и этот стиль переопределит стиль кнопки, который вы объединили в тему с помощью ContextThemeWrapper. - person Newtonx; 09.02.2015
comment
При использовании этого решения в сочетании с макетом потока и установкой фигуры, которую можно рисовать в стиле, настройка поля для @style не распознавалась. Я использовал это сначала, но после добавления формы, которую можно рисовать в стиль, мне пришлось пойти с принятым ответом - надуть назначенный XML-файл, в котором используется стиль. - person Gene Bo; 21.11.2016
comment
Как ни странно, со счетчиками он устанавливает стиль для каждого отдельного выпадающего элемента, а не для самого счетчика, что может быть удобно для тех, кто создает счетчики программно, но не то, что я собирался - person Rowan Berry; 19.12.2019

Вы можете установить стиль в конструкторе (но стили не могут быть динамически изменены / установлены).

View(Context, AttributeSet, int) (int - это атрибут в текущей теме, который содержит ссылку на стиль)

Ответ Ромена Гая

ссылка

person Dandre Allison    schedule 19.02.2013
comment
ваш ответ вводит в заблуждение - вы пробовали дочитать эту ветку до конца? - person andr; 14.03.2013
comment
Как это вводит в заблуждение? Принятый ответ вводит в заблуждение, потому что Ромен Гай прямо говорит, что вы можете установить стиль программно. Просто нет возможности его динамически изменять. Однако этот тред, похоже, не думает, что это так. - person Dandre Allison; 15.03.2013
comment
Осторожно, для этого вызова требуется уровень API 11. - person Martin Capodici; 21.06.2014
comment
пожалуйста, добавьте цитаты к ответу - person Paul Verest; 24.10.2014
comment
@PaulVerest, это не цитата. - person Dandre Allison; 26.10.2014
comment
@MartinCapodici не понимает, что вы имеете в виду, говоря о вызове, требующем уровня API 11. developer.android.com/reference/android/view/, android.util.AttributeSet, int) существует с уровня API 1. - person Dandre Allison; 26.10.2014
comment
Stackoverflow говорит, что ответ не заключается в обмене ссылками, но должен включать достаточно информации из указанного ресурса. Пользователи не должны читать ссылку, чтобы судить, лучший ли ответ. - person Paul Verest; 27.10.2014
comment
Последний int - не ресурс стиля. Это атрибут в текущей теме, который содержит ссылку на ресурс стиля, который предоставляет значения по умолчанию для представления. - person rve; 15.01.2015
comment
@rve спасибо, ты прав. Я обновил описание как таковое - person Dandre Allison; 10.02.2020

Параметр int defStyleAttr не определяет стиль. Из документации Android:

defStyleAttr - атрибут в текущей теме, который содержит ссылку на ресурс стиля, который предоставляет значения по умолчанию для представления. Может быть 0, чтобы не искать значения по умолчанию.

Для настройки стиля в конструкторе View у нас есть 2 возможных решения:

  1. С использованием ContextThemeWrapper:

    ContextThemeWrapper wrappedContext = new ContextThemeWrapper(yourContext, R.style.your_style);
    TextView textView = new TextView(wrappedContext, null, 0);
    
  2. С конструктором с четырьмя аргументами (доступен начиная с LOLLIPOP):

    TextView textView = new TextView(yourContext, null, 0, R.style.your_style);
    

Ключевой момент для обоих решений - параметр defStyleAttr должен быть равен 0, чтобы применить наш стиль к представлению.

person DmitryArc    schedule 05.02.2017
comment
Спасибо за ответ. Я могу подтвердить, что это сработало для меня. И особая благодарность за примечание в конце вашего ответа. - person Danish Ansari; 29.08.2020
comment
Стиль почему-то не работает для атрибутов полей. Почему? - person deadfish; 23.03.2021

Динамическое изменение стилей не поддерживается (пока). Вы должны установить стиль до создания представления через XML.

person Chris Cashwell    schedule 30.03.2011
comment
что на самом деле одно и то же - person njzk2; 04.01.2012
comment
@ njzk2 спасибо ... очевидно, не думал о его комментарии перед публикацией. Невозможно установить стиль программно до создания пользовательского интерфейса, поэтому тот же код будет использоваться для изменения или установки стиля программно. - person Chris Cashwell; 05.01.2012

Принятый ответ был для меня отличным решением. Единственное, что нужно добавить, - это метод inflate().

В принятом ответе все android:layout_* параметры применяться не будут.

Причина в том, что это невозможно изменить, потому что null был передан как ViewGroup parent.

Вы можете использовать это так:

View view = inflater.inflate(R.layout.view, parent, false);

а parent - это ViewGroup, откуда вам нравится настраивать android:layout_*.

В этом случае будут установлены все относительные свойства.

Надеюсь, это будет кому-то полезно.

person Anor    schedule 10.04.2015

При использовании настраиваемых представлений, которые могут использовать наследование стилей (или атрибуты, допускающие стили событий), вы должны изменить второй конструктор, чтобы не потерять стиль. Это сработало для меня, без необходимости использовать setTextAppearence ():

public CustomView(Context context, AttributeSet attrs) {
    this(context, attrs, attrs.getStyleAttribute());
}
person saiyancoder    schedule 10.01.2014

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

Третий параметр конструктора View принимает тип attr в вашей теме в качестве исходного кода ниже:

public TextView(Context context, AttributeSet attrs) {
    this(context, attrs, com.android.internal.R.attr.textViewStyle);
}

Таким образом, вы должны передать тип R.attr. **, а не R.style. **

В своих кодах я сделал следующие шаги:

Во-первых, настройте индивидуальный атрибут attr, который будет использоваться темами в attr.xml.

<attr name="radio_button_style" format="reference" />

Во-вторых, укажите свой стиль в используемой теме в style.xml.

 <style name="AppTheme" parent="android:Theme.Translucent">
    <!-- All customizations that are NOT specific to a particular API-level can go here. -->
    <item name="radio_button_style">@style/radioButtonStyle</item>
</style>
<style name="radioButtonStyle" parent="@android:style/Widget.CompoundButton.RadioButton">
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">64dp</item>
    <item name="android:background">#000</item>
    <item name="android:button">@null</item>
    <item name="android:gravity">center</item>
    <item name="android:saveEnabled">false</item>
    <item name="android:textColor">@drawable/option_text_color</item>
    <item name="android:textSize">9sp</item>
</style>

В конце концов, используйте это!

            RadioButton radioButton = new RadioButton(mContext, null, R.attr.radio_button_style);

представление, созданное программно, будет использовать указанный стиль в вашей теме.

Вы можете попробовать и надеяться, что это сработает для вас идеально.

person mrtwo    schedule 17.10.2016

Мы можем использовать TextViewCompact.setTextAppearance(textView, R.style.xyz).

Android doc для справки.

person Kshitij Jain    schedule 02.09.2019

Я тестировал только EditText, но вы можете использовать метод

public void setBackgroundResource (int остаток)

для применения стиля, определенного в файле XML.

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

С уважением.

person floydaddict    schedule 11.07.2012
comment
Согласно документации, это должно работать только с чертежи, а не стиль. Таким образом, если это действительно работает, то это случайно и не стоит на это полагаться. - person Heinzi; 14.09.2012