如何让Android的TableLayout填满屏幕?

27

我正在与Android糟糕的布局系统作斗争。 我试图让表格填满屏幕(简单吧?),但这非常难。

我在XML中以某种方式使其工作,像这样:

<?xml version="1.0" encoding="utf-8"?>

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:layout_width="fill_parent">
<TableRow android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="1">
<Button android:text="A" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_weight="1"/>
<Button android:text="B" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_weight="1"/>
</TableRow>
<TableRow android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="1">
<Button android:text="C" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_weight="1"/>
<Button android:text="D" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_weight="1"/>
</TableRow>

然而我无法在Java中使其工作。我已经尝试了无数的LayoutParams组合,但仍然没有任何效果。这是我能得到的最好结果,只填充了屏幕的宽度而不是高度:

    table = new TableLayout(this);
    // Java. You suck.
    TableLayout.LayoutParams lp = new TableLayout.LayoutParams(
                                    ViewGroup.LayoutParams.FILL_PARENT,
                                    ViewGroup.LayoutParams.FILL_PARENT);
    table.setLayoutParams(lp); // This line has no effect! WHYYYY?!
    table.setStretchAllColumns(true);
    for (int r = 0; r < 2; ++r)
    {
        TableRow row = new TableRow(this);
        for (int c = 0; c < 2; ++c)
        {
            Button btn = new Button(this);
            btn.setText("A");
            row.addView(btn);
        }
        table.addView(row);
    }

显然,Android文档没有提供帮助。有人有什么想法吗?


3
你的问题中充满了负面情绪,我认为不会有很多人急于给你提供答案。 - Mark B
3
我知道。当你花费很长时间去完成本应该简单的任务时,这真的让人感到沮丧。 - Timmmm
5
对于“Android 的落后布局系统”给予“+1”的支持。 - Petr Peller
5个回答

35

以上讨论中有两个错误。

  1. 通过指定TableLayout.LayoutParamsTableRow.LayoutParams并使用适当的构造函数,例如:

TableLayout.LayoutParams rowInTableLp = new TableLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, 1.0f);
  • 小部件必须具有其父级的LayoutParams。因此,行必须使用TableLayout.LayoutParams

  • TableLayout table = new TableLayout(this);
    // Java. You succeed!
    FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.FILL_PARENT,
            ViewGroup.LayoutParams.FILL_PARENT);
    table.setLayoutParams(lp);
    table.setStretchAllColumns(true);
    
    TableLayout.LayoutParams rowLp = new TableLayout.LayoutParams(
            ViewGroup.LayoutParams.FILL_PARENT,
            ViewGroup.LayoutParams.FILL_PARENT,
            1.0f);
    TableRow.LayoutParams cellLp = new TableRow.LayoutParams(
            ViewGroup.LayoutParams.FILL_PARENT,
            ViewGroup.LayoutParams.FILL_PARENT,
            1.0f);
    for (int r = 0; r < 2; ++r)
    {
        TableRow row = new TableRow(this);
        for (int c = 0; c < 2; ++c)
        {
            Button btn = new Button(this);
            btn.setText("A");
            row.addView(btn, cellLp);
        }
        table.addView(row, rowLp);
    }
    setContentView(table);
    

    感谢Romain Guy在Android开发者论坛上的评论提供了解决方案


    哇,我已经苦苦挣扎了很久,终于这个例子可以用了!谢谢! - bk138
    2
    这句话对我很有帮助:'小部件必须具有其父级的LayoutParams。因此,行必须使用TableLayout.LayoutParams' - hhh3112
    1
    我花了好几个小时才读懂这句话…… “小部件必须具有其父布局的LayoutParams。” 谢谢你,你节省了我很多时间! - Bojan

    8

    我终于找到了如何做到这一点的方法。放弃使用TableLayout,只需在垂直布局中使用水平的LinearLayout即可。关键是要设置权重。如果您指定FILL_PARENT但使用默认权重,则无法正常工作:

    LinearLayout buttonsView = new LinearLayout(this);
    buttonsView.setOrientation(LinearLayout.VERTICAL);
    for (int r = 0; r < 6; ++r)
    {
        LinearLayout row = new LinearLayout(this);
        row.setOrientation(LinearLayout.HORIZONTAL);
        for (int c = 0; c < 4; ++c)
        {
            Button btn = new Button(this);
            btn.setText("A");
            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT);
            lp.weight = 1.0f;
            row.addView(btn, lp);
        }
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT);
        lp.weight = 1.0f;
        buttonsView.addView(row, lp);
    }  
    
    ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
    setContentView(buttonsView, lp);
    

    1

    0

    你从未设置行或按钮布局参数,而在发布的xml中却这样做了。更改for循环的细节以设置行布局参数和按钮布局参数,那么它应该会产生与您的xml相同的结果。


    它不行 - 我尝试过了(以多种方式!)。此外,在Android文档中,它说:“TableLayout的子项不能指定layout_width属性。宽度始终为FILL_PARENT。但是,layout_height属性可以由子项定义;默认值为WRAP_CONTENT。如果子项是TableRow,则高度始终为WRAP_CONTENT。”和“TableRow的子项在XML文件中不需要指定layout_width和layout_height属性。TableRow始终强制执行这些值分别为FILL_PARENT和WRAP_CONTENT。” - Timmmm

    0

    如果要设置TableLayout的LayoutParams,我们通常会使用TableLayout.LayoutParams类,但是你会收到一个转换错误,指出TableLayout.LayoutParams无法转换为FrameLayout.LayoutParams。

    因此,如果您想以编程方式设置TableLayout属性,则应使用FrameLayout.LayoutParams。例如:

    FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT,TableLayout.LayoutParams.MATCH_PARENT);
                layoutParams.setMargins(80, 0, 0, 0);
                TableLayout tableLayout = (TableLayout) findViewById(R.id.header_detail);
                tableLayout.setLayoutParams(layoutParams);
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接