如何在代码中动态设置layout_weight属性?

301

我如何从Java代码动态设置Android中按钮的layout_weight属性值?


它将非常类似于这个问题/答案:https://dev59.com/_W445IYBdhLWcg3w6eRo#4639012 和这个问题:https://dev59.com/g2445IYBdhLWcg3w6eXz#4637266 - Rich Schuler
如果您已经在布局(xml)文件中定义了视图,则创建新的LayoutParams会覆盖在xml文件中定义的其他参数。因此,首先应该使用“getLayoutParams”。请参见完整答案https://dev59.com/P2445IYBdhLWcg3w6eRo#38011495 - Shirish Herwade
13个回答

552
您可以将其作为LinearLayout.LayoutParams构造函数的一部分传递进去:
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(
    LayoutParams.MATCH_PARENT,
    LayoutParams.MATCH_PARENT,
    1.0f
);
YOUR_VIEW.setLayoutParams(param);
最后一个参数是权重。

56
如果您不想从double转换为float,只需输入1.0f即可。 - Xample
11
如果没有小数位,可以更简单地输入1f - sandalone
5
如果父布局是“相对布局(Relative)”,该怎么办? - Pratik Butani
10
如果父布局是相对布局,你就不需要使用权重(weights)属性。 - invertigo
3
我认为,LayoutParams.MATCH_PARENT 中的两个参数之一应该被更改为0。 - CoolMind
显示剩余4条评论

132

使用 LinearLayout.LayoutParams

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
    LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
params.weight = 1.0f;
Button button = new Button(this);
button.setLayoutParams(params);

编辑:啊,Erich的答案更简单!


28
Erich的回答可能更容易书写,但是你的更易于阅读,因为它表明了1.0f所使用的属性。 - Johan
3
你可以通过调用“view.getLayoutParams()”来动态修改权重,然后修改其值。 - RobGThai
1
FILL_PARENT已被弃用,应使用MATCH_PARENT代替。 - Simon Forsberg
2
@LocalPCGuy 不是这样的。只要你的目标 SDK >= 8(你应该是如此),即使在旧设备上,也可以使用MATCH_PARENT代替FILL_PARENT - Kevin Coppock
2
@LocalPCGuy 现在没有人再使用API 7或更低版本了。如果您想让您的应用程序与API 7或更低版本兼容,那么在担心FILL_PARENTMATCH_PARENT之前,您可能会遇到许多其他问题。 - Simon Forsberg
显示剩余2条评论

94
如果您已经在布局(xml)文件中定义了视图,只想在程序中动态更改权重,则此方法更好。
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)   
mButton.getLayoutParams();
params.weight = 1.0f;
mButton.setLayoutParams(params);

新建一个LayoutParams会覆盖在xml文件中定义的其他参数,例如边距,或者你需要在LayoutParams中指定所有这些参数。


3
通过设置 "params.weight = 1f;",您已经在LayoutParams对象上设置了权重。不需要调用 "mButton.setLayoutParams(params);"。 - MrMaffen
2
不,你必须调用 setLayoutParams。 - SIr Codealot
1
这实际上是最优雅的答案,它直接更改了特定的UI对象。最佳答案也很好,比这篇文章还要早。因此,它应该被评为最佳答案。虽然我点赞了这篇文章。 - The Original Android
非常好用!非常感谢 :) - Vinay Vissh
你实际上可以直接调用 mButton.requestLayout() 而不是 setLayoutParams,因为你只是改变了一个值。setLayoutParams 在内部调用了 requestLayout - JohnnyLambada
显示剩余2条评论

32
如果具有宽度、高度和重量的构造函数不起作用,请尝试使用具有宽度和高度的构造函数,然后手动设置重量。
如果您希望根据重量设置宽度,请在构造函数中将宽度设置为0。高度同理。 以下代码适用于我。
LinearLayout.LayoutParams childParam1 = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT);
childParam1.weight = 0.3f;
child1.setLayoutParams(childParam1);

LinearLayout.LayoutParams childParam2 = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT);
childParam2.weight = 0.7f;
child2.setLayoutParams(childParam2);

parent.setWeightSum(1f);
parent.addView(child1);
parent.addView(child2);

正是我想要的!这里每个人都在谈论设置权重,却没有人展示当这些有权重的子视图被添加到父视图时会发生什么!我实际上正在寻找如何在父视图上添加weightSum!谢谢! - sud007

19
如果layoutparams已经在XML或动态定义中定义,则有一个一行代码解决方案:

Here's a one liner:


((LinearLayout.LayoutParams) mView.getLayoutParams()).weight = 1;

1
被低估的答案 - Adam Higgins

15

如果有人正在寻找答案,请使用这个:

LinearLayout.LayoutParams lay = (LinearLayout.LayoutParams) myLayout.getLayoutParams();
lay.weight = 0.5;

如果你是从xml文件初始化你的布局,那么这比为线性布局提供新的布局参数要方便得多。


这应该是被接受的答案,因为它不会修改任何先前设置的变量,如宽度/高度/边距/填充等。在改变权重的同时,所有内容都被保留和重复使用。 - MrMaffen
2
如果要设置layout_weight的视图已经被布局,您需要调用View.requestLayout()来更新。 - Attacktive

8

LinearLayout.LayoutParamsTableLayout.LayoutParams 两者都可以使用,对于按钮来说正确的是 TableRow.LayoutParams。即:

            TableRow.LayoutParams buttonParams = new TableRow.LayoutParams(
                    TableRow.LayoutParams.MATCH_PARENT,
                    TableRow.LayoutParams.WRAP_CONTENT, 1f);

使用MATCH_PARENTWRAP_CONTENT是相同的。


3
FILL_PARENT已经被弃用,应该使用MATCH_PARENT代替。 - Simon Forsberg
我认为LayoutParams.MATCH_PARENT应该改成0。 - CoolMind
你调用直接父级的 LayoutParams。我猜测你试图在没有父级布局 LinearLayout 的情况下使用了 LinearLayout.LayoutParams,因此导致了程序崩溃。 - Abandoned Cart

4
如果您已经在布局(xml)文件中定义了视图并且只想通过编程方式更改权重,则创建新的LayoutParams会覆盖您在xml文件中定义的其他参数。
因此,首先应使用“getLayoutParams”,然后再使用“setLayoutParams”。
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mButton.getLayoutParams(); params.weight = 4f; mButton.setLayoutParams(params);

3
我已经通过添加这行代码完成了我的任务!
LinearLayout.LayoutParams mylayout = (LinearLayout.LayoutParams)   
myview.getLayoutParams();
mylayout.weight = 2;
myview.setLayoutParams(mylayout);

0

使用 Kotlin,您可以做类似于以下操作:

import android.content.Context
import android.support.v4.content.ContextCompat
import android.support.v7.widget.CardView
import android.widget.*

import android.widget.LinearLayout

class RespondTo : CardView {
    constructor(context: Context) : super(context) {
        init(context)
    }

    private fun init(context: Context) {


        val parent = LinearLayout(context)

        parent.apply {
            layoutParams = LinearLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
                    FrameLayout.LayoutParams.WRAP_CONTENT, 1.0f).apply {
                orientation = LinearLayout.HORIZONTAL

                addView(EditText(context).apply {
                    id = generateViewId()
                    layoutParams = LinearLayout.LayoutParams(0,
                            LinearLayout.LayoutParams.WRAP_CONTENT, 0.9f).apply {
                    }
                })
                addView(ImageButton(context).apply({
                    layoutParams = LinearLayout.LayoutParams(0,
                            LinearLayout.LayoutParams.WRAP_CONTENT, 0.1f)
                    background = null
                    setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_save_black_24px))
                    id = generateViewId()
                    layoutParams = RelativeLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                            LinearLayout.LayoutParams.WRAP_CONTENT).apply {
                        addRule(RelativeLayout.ALIGN_PARENT_RIGHT)
                        // addRule(RelativeLayout.LEFT_OF, myImageButton.id)
                    }
                }))
            }
        }
        this.addView(parent)
    }
}

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