【问题标题】:Programmatically create a textview with 0dp and layout weight 1以编程方式创建一个 0dp 和布局权重为 1 的文本视图
【发布时间】:2015-05-03 10:19:42
【问题描述】:

我正在开发一个 Android 项目,但布局有问题。

我有一个JSONArray,我循环膨胀一个新的 TableRow 并在循环内循环 JSON 数组中的另一个数组以用字段填充它。通过扩展 XML 文件并将此视图添加到表行来填充字段。但是,目前该行中没有任何显示。

下面是我的 TableRow XML 文件:

<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/white"/>

下面是我的 TextView XML:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:textColor="@color/black"
    android:padding="5dp"/>

下面是我如何填充 TableRow 和 TextView:

for (int i = 0; i < result.length(); i++) {
    final TableRow tr = (TableRow) getLayoutInflater(getArguments()).inflate(R.layout.result_table_row_light_theme, resultTable, false);
    if (i == 0) {
        tr.setBackgroundColor(getResources().getColor(R.color.appPrimaryColour));
    } else if (i % 2 == 0) {
        if (settings.getInt(Defines.SharedPreferenceSettings.APPLICATION_THEME,
                com.BoardiesITSolutions.Library.R.style.LibAppTheme) == com.BoardiesITSolutions.Library.R.style.LibAppTheme) {
            tr.setBackgroundColor(getResources().getColor(R.color.resultRowLightThemeAlternateRow));
        }
    }
    JSONArray array = result.getJSONArray(i);
    for (int j = 0; j < array.length(); j++) {
        final TextView textView;
        textView = (TextView) getLayoutInflater(getArguments()).inflate(R.layout.result_textview, tr, false);
        textView.setText(array.getString(j));
        if (i == 0) {
            textView.setTypeface(null, Typeface.BOLD);
            textView.setGravity(Gravity.CENTER_HORIZONTAL);
        }
        getActivity().runOnUiThread(new Runnable() {

            @Override
            public void run() {
                tr.addView(textView);
            }
        });
    }
    getActivity().runOnUiThread(new Runnable() {

        @Override
        public void run() {
            resultTable.addView(tr);
        }
    });
}

如果我更改我的 TextView XML 文件,使 layout_width 为 wrap_parent 而不是 0dp,那么所有内容都会显示在屏幕上。

但是,当 textview 为 0dp 且 layout_weight 为 1 时,则不会显示任何内容,但是我希望每个文本视图均匀分布在屏幕宽度上以填充空间。

我可能应该提到的是,不知道是否有区别,TableView 位于 Horizo​​ntalScrollView 中。行应该适合屏幕的宽度,如果数据小于屏幕,但如果行不适合,那么视图将是水平滚动的。

更新 1

以下是承载 TableLayout 的 XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">
    <ScrollView 
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scrollbars="horizontal">
        <LinearLayout 
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical">
            <HorizontalScrollView 
                android:layout_width="fill_parent"
                android:layout_height="fill_parent">
                <TableLayout android:id="@+id/resultTable"
                    android:stretchColumns="*"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content">
                </TableLayout>
            </HorizontalScrollView>
        </LinearLayout>
    </ScrollView>
</RelativeLayout>

【问题讨论】:

  • 每个文本视图上的 0dp 表示没有宽度,因此不会显示任何内容。
  • 但通常如果你有 layout_weight 它会填满可用空间。由于它们的权重均为 1,因此它们应该在屏幕上均匀分布。当所有文本视图作为 XML 的一部分添加在一起而不是以编程方式创建时就是这种情况
  • 嗯,没错,我错过了。 TableLayout 的 XML 是什么?确保其宽度未设置为 wrap_content,因为 layout_weight 仅适用于 TableRow 中的额外空间。
  • TableLayout 和 Horizo​​ntal Scroll View 设置为 fill_parent。我已将 TableLayout 的 XML 添加到我的问题中,以防万一
  • 在滚动方向调用 match_parent 对滚动视图的子视图不起作用。

标签: android xml


【解决方案1】:

我可能应该提到的是,不知道是否有区别,TableView 在 Horizo​​ntalScrollView 内。

将滚动容器内的子视图告知match_parent 或以任何方式填充可用空间是一个逻辑错误。像ScrollViewHorizontalScrollView 这样的滚动容器将其唯一的子视图测量为UNSPECIFIED,以便子视图可以在该方向上超出父视图(因此可以滚动)。

没有为滚动容器的子级提供可以填充的“可用空间”,如果父级的尺寸定义不明确,布局权重等操作将无效。

行应该适合屏幕的宽度,如果数据小于屏幕,但如果行不适合,那么视图将是水平滚动的。

您正在寻找的功能是fillViewport (docs link),如果测量的宽度(在水平情况下)小于父级,它会告诉滚动容器强制子级匹配它的大小。使用它来代替施加权重。

【讨论】:

  • 非常感谢,我已经为此苦苦挣扎多年。使用 fillViewPort 修复它
【解决方案2】:

试试这个:

public void createTextView(Context context, LinearLayout parent) {
    final TextView v = new TextView(context);
    parent.addView(v); // Mandatory!
    v.post(new Runnable() { // In UI Thread. View Must be added to parent before getting layout params!
        @Override
        public void run() {

             // Get params:
             LinearLayout.LayoutParams lParams = (LinearLayout.LayoutParams) v.getLayoutParams();

             // Set only target params:
             lParams.width = 0;
             lParams.weight = 1;
             v.setLayoutParams(lParams);
        }
    });
}

【讨论】:

    【解决方案3】:

    您可以尝试在 XML 中进行布局(只是为了调试它,使用虚拟数据)?它是否按预期工作?

    docs 提到:

    TableRow 的子项不需要在 XML 文件中指定 layout_width 和 layout_height 属性。 TableRow 始终强制这些值分别为 MATCH_PARENT 和 WRAP_CONTENT。

    不确定这是否意味着如果您尝试设置这些值也会造成混乱。正如您所发现的,如果设置了它们,显然不仅仅是忽略它们。

    另一部分说TableRow 的父级应该是TableLayout - 是resultTable 的类型(你提到了TableView) - 否则它将表现为水平方向的LinearLayout .

    【讨论】:

    • 它在表格布局中,我已将 XML 包含在我的问题中。我已经完成了你建议的测试。如果 EditText 设置了 layout_width 和 layout_weight ,我会得到相同的行为,即不显示任何内容,如果我从 TableRow 中的 EditTexts 中省略这些参数,那么它可以工作
    • “归结为将 android:stretchColumns="1" 添加到 TableLayout 根目录并将 android:layout_width="0dp" 设置为 TableRow 中的所有子项” -也可以在这里查看该答案的 cmets:stackoverflow.com/questions/6647177/…
    • 即使将所有子项设置为 0 宽度并将拉伸列设置为 1,我仍然遇到同样的问题
    猜你喜欢
    • 1970-01-01
    • 2012-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多