【问题标题】:How to add margin space between buttons programmatically added to a LinearLayout?如何在以编程方式添加到 LinearLayout 的按钮之间添加边距空间?
【发布时间】:2013-02-28 17:03:54
【问题描述】:

我在运行时将按钮添加到 LinearLayout(垂直方向)...

private void addButtons(String[] titles) {
    for (String title : titles) {
        Button button = ButtonBuilder.getButton(getActivity());
        button.setText(title);
        mButtonsLayout.addView(button);
    }
}

每个按钮都有一个用 XML 定义的样式。

<!-- styles.xml -->
<style name="Button">
    <item name="android:layout_width">match_parent</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:gravity">center</item>
    <item name="android:layout_margin">8dp</item>
</style>

虽然我定义了layout_margin,但所有按钮都彼此相邻,没有任何间距。如何在它们之间添加边距?


正如 nmw 所建议的,我正在尝试将父布局引入充气机。

private void addButtons(String[] titles) {
    for (String title : titles) {
        Button button = ButtonBuilder.getButton(getActivity(), mButtonsLayout);
        button.setText(title);
        mButtonsLayout.addView(button);
    }
}

..

// ButtonBuilder.java
public static Button getButton(Activity activity, ViewGroup parent) {
    return (Button)activity.getLayoutInflater().inflate(R.layout.custom_button, 
                                                        parent);
}

这会导致异常..

java.lang.ClassCastException: android.widget.LinearLayout cannot be \
   cast to android.widget.Button

【问题讨论】:

  • 查看我对 inflate 在给定父级时返回 ViewGroup 的编辑。

标签: android android-layout runtime android-linearlayout margin


【解决方案1】:

layout_margin 在布局膨胀时将被忽略,因为在实例化时没有父 ViewGroup。框架无法创建布局参数,因为它不知道父 ViewGroup 类型。

要解决此问题,您可以:

1/也可以通过编程方式创建布局参数,就在添加视图之前,您可以在其中设置边距。

2/ 将 ViewGroup 参数添加到 getButton 构建器并传入 mButtonsLayout。然后,当您膨胀 XML 时,将其用作父 ViewGroup(inflate() 上的最后一个参数)。

当使用 2/ 方法时,inflate() 将返回 ViewGroup 而不是 View(在您的情况下为按钮),因此您需要使用 parent.getChildAt(parent.getChildCount()-1) 将按钮从 ViewGroup 中取出.

请参阅LayoutInflater docs 了解膨胀信息。


编辑:

请注意,Builder 将不再作为 getButton() 方法工作。使用 ViewGroup 参数时,按钮会立即添加到父视图。

public static Button addButton(Activity activity, ViewGroup parent) {
    activity.getLayoutInflater().inflate(R.layout.custom_button, parent);
    return (Button) parent.getChildAt(parent.getChildCount() - 1);
}

因此,您不能再在主类中添加视图。

// mButtonsLayout.addView(button); // Remove this

否则会导致以下错误:

java.lang.IllegalStateException: The specified child already has a parent. \
    You must call removeView() on the child's parent first.

【讨论】:

    【解决方案2】:

    使用它来动态发送保证金

    MarginLayoutParams marginParams = new MarginLayoutParams(backToMainScreenImageView.getLayoutParams());
    marginParams.setMargins(0, 0, (int) UIUtil.getRadialButtonMainMargin(this), 0);
    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(marginParams);
    backToMainScreenImageView.setLayoutParams(layoutParams);
    

    【讨论】:

      【解决方案3】:

      试试这样的:

      FrameLayout.LayoutParams layoutParams = 
         new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, 
                                       LayoutParams.WRAP_CONTENT);
      layoutParams.setMargins(0, 0, 0, 0);
      mButtonsLayout.setLayoutParams(layoutParams);
      

      【讨论】:

      • 这导致java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams cannot be cast to android.widget.FrameLayout$LayoutParams