以编程方式创建具有特定样式的Android视图

Cas*_*ash 15 android

其他问题表明样式不能以编程方式设置,但是View可以使用样式初始化样式,例如从XML加载样式时.

如何View以编程方式(而不是XML)以特定样式初始化a ?我尝试使用View(Context context,AttributeSet attrs,int defStyle),但我不知道要为第二个参数解析什么.传入null导致View未显示

Gio*_*esi 13

我遇到了同样的问题,但到目前为止还没有找到任何以编程方式直接设置样式的实用方法.我想用一些给定类型的小部件填充我的屏幕,让我们说按钮.在布局文件中定义它们是不切实际的.我想以编程方式创建它们,但我还想在样式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>
Run Code Online (Sandbox Code Playgroud)

然后通过派生类"NiceButton"将类"Button"子类化.定义inflater需要的构造函数:

public NiceButton(Context context, AttributeSet attrs) {
    super(context, attrs);
}
Run Code Online (Sandbox Code Playgroud)

然后定义另一个构造函数,其目的是克隆现有按钮:

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
}
Run Code Online (Sandbox Code Playgroud)

在布局文件中,只定义第一个按钮.例如,假设您要将按钮放在表格中:

<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>
Run Code Online (Sandbox Code Playgroud)

请注意,使用了widget类的完全限定名称; 显然,您必须将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!");
    }
};
Run Code Online (Sandbox Code Playgroud)

注意视图id如何用作按钮数组中的索引.因此,您需要按钮的ID为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);
    }
Run Code Online (Sandbox Code Playgroud)

按下某些按钮后,屏幕显示如下: 在此输入图像描述

好吧,有一些代码涉及,但最终你可以编程创建任意数量的小部件,并仍然将其属性定义为样式.


bee*_*tra 10

如果要为视图设置样式,则有两种选择:最简单的方法是仅指定代码中的所有元素:

button.setTextColor(Color.RED);
button.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
Run Code Online (Sandbox Code Playgroud)

另一种选择是在XML中定义样式,并将其应用于视图.在一般情况下,您可以使用a ContextThemeWrapper:

ContextThemeWrapper newContext = new ContextThemeWrapper(baseContext, R.style.MyStyle);
button = new Button(newContext);
Run Code Online (Sandbox Code Playgroud)

要更改TextView(或其子类,如Button)上与文本相关的属性,有一种特殊方法:

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

最后一个不能用于更改所有属性; 例如,要更改填充,您需要使用a ContextThemeWrapper.但是对于文本颜色,大小等,您可以使用setTextAppearance.


Kar*_*ran 5

AttributeSet包含以xml指定的属性列表(例如layout_width,layout_height等)。

如果将其传递为null,则应显式设置视图的高度/宽度。

  • AttributeSet似乎没有构造函数。是否可以不使用xml来构建它? (2认同)