Создание представления Android с определенным стилем программно - PullRequest
15 голосов
/ 01 июня 2010

Другие вопросы говорят, что стиль не может быть установлен программно, но View может быть инициализирован со стилем, например, при загрузке из XML.

Как можно программно инициализировать View с определенным стилем (не в XML)? Я попытался использовать View (контекстный контекст, атрибуты AttributeSet, int defStyle) , но я не знаю, что анализировать для второго аргумента. Передача null приводит к тому, что View не отображается

Ответы [ 3 ]

13 голосов
/ 04 мая 2011

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

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

Ниже приведен пример.

В файле стиля определите стиль для ваших кнопок. Например:

<style name="niceButton">
    <item name="android:layout_width">160dip</item>
    <item name="android:layout_height">60dip</item>
    <item name="android:gravity">center</item>
    <item name="android:textSize">18dip</item>
    <item name="android:textColor">#000000</item>
</style>

Затем подкласс класса «Button», получая класс «NiceButton». Определите конструктор, который понадобится инфлятору:

public NiceButton(Context context, AttributeSet attrs) {
    super(context, attrs);
}

Затем определите другой конструктор, целью которого является клонирование существующей кнопки:

public NiceButton(int id, NiceButton origButton) {
    super(origButton.getContext());
    setId(id);
    setLayoutParams(origButton.getLayoutParams());
    setGravity(origButton.getGravity());
    setPadding(origButton.getPaddingLeft(),
                    origButton.getPaddingTop(),
                    origButton.getPaddingRight(),
                    origButton.getPaddingBottom());
    setTextSize(TypedValue.COMPLEX_UNIT_PX, origButton.getTextSize());
    setTextColor(origButton.getTextColors());
    // ... also copy whatever other attributes you care about
}

В вашем файле макета определите только первую из ваших кнопок. Предположим, например, что вы хотите поместить свои кнопки в таблицу:

<TableLayout android:id="@+id/button_table"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">

    <TableRow android:id="@+id/button_row_0">
        <com.mydomain.mypackage.NiceButton
                    style="@style/niceButton" android:id="@+id/button_0" />
        <!-- More rows/buttons created programmatically -->
    </TableRow>

</TableLayout>

Обратите внимание, что используется полное имя класса виджета; очевидно, вам придется заменить com.mydomain.mypackage на фактическое имя пакета.

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

NiceButton[] mButtonViews = new NiceButton[10];

private View.OnClickListener mNiceButtonClickListener = new View.OnClickListener() {
    public void onClick(View view) {
        int i = view.getId();
        mButtonViews[i].setText("PRESSED!");
    }
};

Обратите внимание, как идентификатор вида используется в качестве индекса в массиве кнопок. Таким образом, вам нужно, чтобы ваши кнопки имели идентификатор от 0 до n-1.

Наконец, вот как вы можете создавать свои кнопки в методе onCreate:

    // Retrieve some elements from the layout
    TableLayout table = (TableLayout)findViewById(R.id.button_table);
    TableRow row = (TableRow)findViewById(R.id.button_row_0);
    NiceButton origButton = (NiceButton)findViewById(R.id.button_0);

    // Prepare button 0
    origButton.setId(0);
    origButton.setText("Button 0");
    origButton.setOnClickListener(mNiceButtonClickListener);
    mButtonViews[0] = origButton;

    // Create buttons 1 to 10
    for (int i = 1; i < 10; i++) {
        if (i % 2 == 0) {
            row = new TableRow(this);
            table.addView(row);
        }
        NiceButton button = new NiceButton(i, origButton);
        button.setText("Button " + i);
        button.setOnClickListener(mNiceButtonClickListener);
        mButtonViews[i] = button; 
        row.addView(button);
    }

Вот как выглядит экран после нажатия некоторых кнопок: enter image description here

Ну, есть некоторый код, но, в конце концов, вы можете создать столько виджетов, сколько захотите программно, и при этом их атрибуты будут определены как стиль.

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

Если вы хотите стилизовать вид, у вас есть 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.

5 голосов
/ 01 июня 2010

AttributeSet содержит список атрибутов, указанных в XML (например, layout_width, layout_height и т. Д.).

Если вы передаете его как ноль, то вы должны явно установить высоту / ширину просмотра.

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