Встановити стиль для TextView програмно


249

Я намагаюся використовувати TextViewконструктор у такому стилі:

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

Однак, коли я це роблю, виглядає, що текстовий вигляд не сприймає стиль (я перевірив стиль, встановивши його на статичний об'єкт).

Я також спробував використовувати, myText.setTextAppearance(MyActivity.this, R.style.my_style)але це також не працює.

Відповіді:


318

Я не вірю, що ви можете встановити стиль програмно. Щоб уникнути цього, ви можете створити файл шаблону xml-файл із призначеним стилем, наприклад, у res / layout створити 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);

Сподіваюсь, це допомагає.


1
Якщо це перемагає відповідь Дандре Еллісона, це те, що для нього не потрібен API v11.
Мартін Каподічі

2
Це могло б спрацювати, але це не має сенсу. Як це можливо встановити за допомогою файлу xml? якщо не програмно . Є причини не використовувати файли xml, одна з них - це я використовую для написання коду для створення інтерфейсу, тому я не хочу вивчати новий спосіб робити це, оскільки моя пам'ять обмежена, і я хочу залишити трохи місця для інші речі.
Іхароб Аль Асімі

@IharobAlAsimi правильно, все можна зробити програмно, і LayoutInflater знає все про перетворення XML в об'єкти. На жаль, багато таких речей приховано під приватними API, і єдиний спосіб створення деяких об'єктів - це надання AttributeSet конструктору.
Miha_x64

На відміну від усіх інших відповідей, це насправді працювало зі спінерами, тому золота зірка для вас
Роуен Беррі

121

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

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

Редагувати: це стосується контексту


50
Ваша відповідь працює до тих пір, поки все, що ви робите, маніпулює «стилем» тексту. Це не спрацьовує, якщо ви намагаєтеся зробити в TextView інші речі, такі як додавання прокладок або поля. Отже, я не кажу, що ви помиляєтесь, але ваша відповідь обмежена. Надуваність подання під час виконання - єдиний спосіб застосувати комплексний стиль.
Білл Мот

1
Обидва рішення використання надутого шаблону та використання setTextAppearance є розумними. Для вирішення проблеми padding / margins для 2-го рішення ви можете зателефонувати textView.setLayoutParams (layoutParams)
AlanKley

Цей метод був застарілий на рівні 23 API. Замість цього використовуйте setTextAppearance (int) в API 23+.
Сергій

Переконайтеся, що версія принаймні API 23 (M)
Br0thazS0ul

4
використовуйте метод з бібліотеки підтримки,TextViewCompat.setTextAppearance
Rubin Yoo

97

Ви можете передати ContextThemeWrapper конструктору так:

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

1
чудові речі! єдиний спосіб я міг програмно задавати стилі, підтримуючи API 8.
tbraun

Чомусь це не впливає на стиль моєї кнопки. Я визначив свій стиль як: <style name="TabButton"><item name="android:background">@drawable/tabbar_button_bkgnd</item>...</style>. І тоді я закликаю його конструкції: new Button(new ContextThemeWrapper(context, R.style.TabButton));. Але кнопка просто ігнорує мої налаштування. Чи роблю тут щось не так?
Алекс Н.

@ AlaksiejN. Вам слід успадковувати такий стиль віджетів. Так якparent="@android:style/Widget.Button"
maxcanna

@maxcanna Чомусь додавання parentтрохи не змінилося. Тому я просто пішов із inflateрішенням.
Алекс Н.

11
@AliakseiN. Потрібно використовувати конструктор 3-arg, наприклад new Button(new ContextThemeWrapper(context, R.style.TabButton), null, 0). В іншому випадку буде застосовано стиль кнопки за замовчуванням, і цей стиль замінить стиль кнопки, який ви об'єднали в тему через ContextThemeWrapper.
Ньютонкс

17

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

View(Context, AttributeSet, int)( intатрибут в поточній темі, що містить посилання на стиль)

Відповідь від Ромена Гая

довідник


ваша відповідь оманлива - ви намагалися прочитати цю тему до кінця?
андр

3
Як це ввести в оману? Прийнята відповідь вводить в оману, тому що Ромен Гай прямо говорить, що можна «задати» стиль програмно. Просто немає засобу, який би міг динамічно змінювати. Схоже, ця тема не вважає, що це так.
Дандре Еллісон

1
Остерігайтеся, для цього дзвінка потрібен рівень 11 API
Мартін Каподічі

1
@PaulVerest це не цитата.
Дандре Еллісон

6
Останній int не є ресурсом стилю. Це "Атрибут у поточній темі, який містить посилання на ресурс стилю, який забезпечує значення за замовчуванням для перегляду".
rve

11

Параметр 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, щоб застосувати наш стиль до подання.


5

Динамічно змінні стилі не підтримуються (поки що). Ви повинні встановити стиль перед тим, як створювати представлення, через XML.


20
що насправді те саме, що насправді
njzk2

@ njzk2 дякую ... явно не замислювався над його коментарем перед публікацією. Неможливо встановити стиль програмно до того, як створений інтерфейс, тому той самий код буде використаний для зміни або встановлення стилю програмно.
Кріс Кешвелл

3

Прийнята відповідь була для мене чудовим рішенням. Єдине, що слід додати - це inflate()метод.

У прийнятій відповіді всі android:layout_*параметри не застосовуватимуться.

Причина полягає в тому, що це не можна коригувати, тому причину nullпередано як ViewGroup parent.

Ви можете використовувати його так:

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

і parentце те ViewGroup, звідки ви хочете налаштувати android:layout_*.

У цьому випадку будуть встановлені всі відносні властивості.

Сподіваюся, це комусь стане в нагоді.


2

Використовуючи власні представлення, які можуть використовувати спадкування стилів (або атрибути, які можна стилізувати події), ви повинні змінити другий конструктор, щоб не втратити стиль. Це працювало для мене, не потребуючи використання setTextAppearence () :

public CustomView(Context context, AttributeSet attrs) {
    this(context, attrs, attrs.getStyleAttribute());
}

2

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

Третій параметр конструктора 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);

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

Ви можете спробувати, і сподіваюся, що це може спрацювати для вас ідеально.


0

Я протестував лише EditText, але ви можете використовувати метод

public void setBackgroundResource (int залишається)

застосувати стиль, визначений у XML-файлі.

Sine цей метод належить View, я вважаю, він буде працювати з будь-яким елементом інтерфейсу.

з повагою


Згідно з документацією, це має працювати лише з малюнком, а не зі стилем. Таким чином, якщо це справді працює, це лише «випадково», і ви не повинні на це покладатися.
Хайнзі

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.