如何创建具有相等宽度的按钮?

时间:2021-04-12 15:01:26

I want to display three buttons in the middle of a screen, and have the three buttons all be the same width, though they will have text labels of different lengths.

我想在屏幕中间显示三个按钮,并且三个按钮都具有相同的宽度,但它们将具有不同长度的文本标签。

Just adding three buttons with text labels of different lengths produces buttons of different widths.

只需添加三个不同长度的文本标签按钮,即可生成不同宽度的按钮。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center_vertical"
    android:gravity="center">
    <Button
        android:id="@+id/button_1"
        android:layout_height="fill_parent"
        android:layout_width="wrap_content"
        android:text="ABCDEF" />
    <Button
        android:id="@+id/button_2"
        android:layout_height="fill_parent"
        android:layout_width="wrap_content"
        android:text="GHI" />
    <Button
        android:id="@+id/button_3"
        android:layout_height="fill_parent"
        android:layout_width="wrap_content"
        android:text="JKLM" />
</LinearLayout>

default button width wraps contents:
如何创建具有相等宽度的按钮?

默认按钮宽度包装内容:

--

Setting the layout_weight to 1 and the layout_width to 0dip on all the buttons causes them to stretch equally to fill the entire screen width. For what I want, such buttons are simply too big, especially on large screens.

在所有按钮上将layout_weight设置为1并将layout_width设置为0dip会使它们均匀拉伸以填充整个屏幕宽度。对于我想要的,这些按钮太大了,特别是在大屏幕上。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center_vertical"
    android:gravity="center">
    <Button
        android:id="@+id/button_1"
        android:layout_height="fill_parent"
        android:layout_width="0dip"
        android:layout_weight="1"
        android:text="ABCDEF" />
    <Button
        android:id="@+id/button_2"
        android:layout_height="fill_parent"
        android:layout_width="0dip"
        android:layout_weight="1"
        android:text="GHI" />
    <Button
        android:id="@+id/button_3"
        android:layout_height="fill_parent"
        android:layout_width="0dip"
        android:layout_weight="1"
        android:text="JKLM" />
</LinearLayout>

layout weight 1 buttons fill screen width:
如何创建具有相等宽度的按钮?

布局重量1按钮填充屏幕宽度:

--

Setting different values for weightSum in the parent LinearLayout can be used to stop the buttons from filling the entire screen, but I don't think this is the path I want to take, because I don't want the buttons to occupy a large portion of the screen on large screen devices. To clarify, using weightSum, I could, for example, set the three buttons to collectively occupy half the screen width, which may look OK on small screens, but on a large screen, the buttons would still occupy half the screen width, and the buttons would simply be much larger than what I want. Perhaps the final solution will be to simply have different layout files for different screens, but I'd rather not go down this path.

在父LinearLayout中为weightSum设置不同的值可以用来阻止按钮填满整个屏幕,但我不认为这是我想要的路径,因为我不希望按钮占据很大一部分在大屏幕设备上的屏幕。为了澄清,使用weightSum,我可以,例如,设置三个按钮共同占据屏幕宽度的一半,这在小屏幕上看起来可以正常,但在大屏幕上,按钮仍然占据屏幕宽度的一半,并且按钮只会比我想要的大得多。也许最终的解决方案是为不同的屏幕设置不同的布局文件,但我不想走这条路。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center_vertical"
    android:gravity="center"
    android:weightSum="5">
    <Button
        android:id="@+id/button_1"
        android:layout_height="fill_parent"
        android:layout_width="0dip"
        android:layout_weight="1"
        android:text="ABCDEF" />
    <Button
        android:id="@+id/button_2"
        android:layout_height="fill_parent"
        android:layout_width="0dip"
        android:layout_weight="1"
        android:text="GHI" />
    <Button
        android:id="@+id/button_3"
        android:layout_height="fill_parent"
        android:layout_width="0dip"
        android:layout_weight="1"
        android:text="JKLM" />
</LinearLayout>

weight sum 5 small screen:
如何创建具有相等宽度的按钮?

重量和5小屏幕:

weight sum 5 large screen:
如何创建具有相等宽度的按钮?

重量和5大屏幕:

--

I also tried many things with TableLayout, but didn't get anything better than just using LinearLayout.

我也尝试过使用TableLayout的很多东西,但没有比使用LinearLayout更好的东西。

GridView is extra-clumsy to use, and I haven't tried it, yet.

GridView使用起来非常笨拙,我还没有尝试过。

So, how does one create buttons with equal widths, preferrably where they are only as wide as necessary to fit the contents of the button with the longest label?

那么,如何创建具有相同宽度的按钮,最好只需要宽度足以使按钮的内容与最长的标签相匹配?

Any advice is appreciated.

任何建议表示赞赏。

(I did search and find this question asked and answered many times, but none of the answers I found resolved what I'm trying to achieve.)

(我确实搜索过并发现这个问题并且多次回答,但我找到的答案都没有解决我想要实现的问题。)

6 个解决方案

#1


5  

Perhaps the final solution will be to simply have different layout files for different screens, but I'd rather not go down this path.

也许最终的解决方案是为不同的屏幕设置不同的布局文件,但我不想走这条路。

Many programmers will use res/layout/ and res/layout-large/ for handling situations like this. In the limited case of the three buttons, you might have alternatives, but usually user interfaces aren't quite that simplistic.

许多程序员将使用res / layout /和res / layout-large /来处理这样的情况。在三个按钮的有限情况下,您可能有其他选择,但通常用户界面并不那么简单。

So, how does one create buttons with equal widths, preferrably where they are only as wide as necessary to fit the contents of the button with the longest label?

那么,如何创建具有相同宽度的按钮,最好只需要宽度足以使按钮的内容与最长的标签相匹配?

To accomplish your "preferrably" [sic] requirement, you would need to create a custom layout class for that. Here is one related to it, for the dashboard pattern, that you might use as a starting point.

要完成“首选”[原文如此]的要求,您需要为此创建自定义布局类。对于仪表板模式,可以使用以下内容作为起点。

#2


3  

If you know in advance what your widest button text will be you can use the android:ems attribute to set your buttons to that width.

如果您事先知道最宽的按钮文本是什么,则可以使用android:ems属性将按钮设置为该宽度。

<Button
    android:id="@+id/my_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:minEms="5"
    android:text="@string/my_button" />

It's not perfect but it's the easiest way that I've found to achieve this look without endlessly fiddling around with layouts.

它并不完美,但它是我发现实现这种外观的最简单方式,而不会无休止地摆弄布局。

#4


0  

Just one additional note from my side!

来自我身边的另外一张纸条!

If you will need to set the width (or height) for the buttons (or any other views with a simple changes of code) that are added at runtime, you can use the code below (it does not depend on orientation):

如果您需要设置在运行时添加的按钮(或具有简单代码更改的任何其他视图)的宽度(或高度),您可以使用下面的代码(它不依赖于方向):

public void AlignButtons(){
    llModules = (LinearLayout) findViewById(R.id.llModules);

    ViewTreeObserver viewTree = llModules.getViewTreeObserver();
    viewTree.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
        public boolean onPreDraw() {

            int childcount = llModules.getChildCount();
            int maxWidth = 0; //int maxHeight = 0;

            String fontPath = "fonts/Isabella-Decor.ttf";
            Typeface tf = Typeface.createFromAsset(getAssets(), fontPath);

            for (int i = 0; i < childcount; i++) {
                LinearLayout v = (LinearLayout)llModules.getChildAt(i);
                View vv = v.getChildAt(0);
                if (vv instanceof Button) {
                    int width = vv.getMeasuredWidth();
                    maxWidth = (maxWidth > width) ? maxWidth : width;
                    //int height = vv.getMeasuredHeight();
                    //maxHeight = (maxHeight > height) ? maxHeight : height;
                }
            }
            for (int i = 0; i < childcount; i++) {
                LinearLayout v = (LinearLayout)llModules.getChildAt(i);
                View vv = v.getChildAt(0);
                if (vv instanceof Button) {
                    LayoutParams params = ((Button) vv).getLayoutParams();
                    params.width = maxWidth;
                    //params.height = maxHeight;
                    ((Button) vv).setLayoutParams(params);

                    // Applying font
                    ((Button) vv).setTypeface(tf);
                }
                vv = v.getChildAt(1);
                if (vv instanceof TextView) {
                    // Applying font
                    ((TextView) vv).setTypeface(tf);
                }
            }

            return true;
        }
    });
}

Here, in my case:

在这里,在我的情况下:

llModule - some layout containing another layout with what we need to align(v.getChildAt(0);) and other(v.getChildAt(1);).

llModule - 包含另一个布局的布局,包含我们需要对齐的内容(v.getChildAt(0);)和其他布局(v.getChildAt(1);)。

LinearLayout v = (LinearLayout)llModules.getChildAt(i); - obtain layout of buttons to align.

LinearLayout v =(LinearLayout)llModules.getChildAt(i); - 获取要对齐的按钮布局。

Other parts are clear to understand.

其他部分很清楚。

Two cycles in this code are quite identical, but I still can't imagine how to combine them (to speed up the execution time).

这段代码中的两个循环完全相同,但我仍然无法想象如何组合它们(以加快执行时间)。

#5


0  

Use this proper code this will help you.

使用这个正确的代码,这将有助于你。

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:weightSum="3">

<Button
    android:id="@+id/button1"
    android:layout_width="0dp"
    android:layout_weight="1"
    android:layout_height="wrap_content"
    android:text="Get the Time"
    android:onClick="showNewDate" />
<Button
    android:id="@+id/button2"
    android:layout_width="0dp"
    android:layout_weight="1"
    android:layout_height="wrap_content"
    android:text="Get the Time"
    android:onClick="showNewDate" />
<Button
    android:id="@+id/button3"
    android:layout_width="0dp"
    android:layout_weight="1"
    android:layout_height="wrap_content"
    android:text="Get the Time"
    android:onClick="showNewDate" />

#6


-1  

Reading this thread, then doing some trial-and-error and noticed that android:layout_width="180px" is an accepted parameter. Now as said, I just stumbled on this, didn't try to use this to solve your three button scenario.

阅读这个帖子,然后做一些试错,并注意到android:layout_width =“180px”是一个可接受的参数。现在如上所述,我只是偶然发现了这一点,没有尝试使用它来解决你的三个按钮场景。

It could well be that things changed since you originally posted. Although I tried this while building for version 1.5. That's old enough... :-)

你最初发布的内容可能会发生变化。虽然我在为1.5版本构建时尝试了这个。那已经足够了...... :-)

Here is the complete main.xml:

这是完整的main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <TextView
        android:id="@+id/dateText"
        android:text="\n\nClick for Date\n\n"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/button"
        android:layout_width="180px"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="Get the Time"
        android:onClick="showNewDate" />

</LinearLayout>

#1


5  

Perhaps the final solution will be to simply have different layout files for different screens, but I'd rather not go down this path.

也许最终的解决方案是为不同的屏幕设置不同的布局文件,但我不想走这条路。

Many programmers will use res/layout/ and res/layout-large/ for handling situations like this. In the limited case of the three buttons, you might have alternatives, but usually user interfaces aren't quite that simplistic.

许多程序员将使用res / layout /和res / layout-large /来处理这样的情况。在三个按钮的有限情况下,您可能有其他选择,但通常用户界面并不那么简单。

So, how does one create buttons with equal widths, preferrably where they are only as wide as necessary to fit the contents of the button with the longest label?

那么,如何创建具有相同宽度的按钮,最好只需要宽度足以使按钮的内容与最长的标签相匹配?

To accomplish your "preferrably" [sic] requirement, you would need to create a custom layout class for that. Here is one related to it, for the dashboard pattern, that you might use as a starting point.

要完成“首选”[原文如此]的要求,您需要为此创建自定义布局类。对于仪表板模式,可以使用以下内容作为起点。

#2


3  

If you know in advance what your widest button text will be you can use the android:ems attribute to set your buttons to that width.

如果您事先知道最宽的按钮文本是什么,则可以使用android:ems属性将按钮设置为该宽度。

<Button
    android:id="@+id/my_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:minEms="5"
    android:text="@string/my_button" />

It's not perfect but it's the easiest way that I've found to achieve this look without endlessly fiddling around with layouts.

它并不完美,但它是我发现实现这种外观的最简单方式,而不会无休止地摆弄布局。

#3


#4


0  

Just one additional note from my side!

来自我身边的另外一张纸条!

If you will need to set the width (or height) for the buttons (or any other views with a simple changes of code) that are added at runtime, you can use the code below (it does not depend on orientation):

如果您需要设置在运行时添加的按钮(或具有简单代码更改的任何其他视图)的宽度(或高度),您可以使用下面的代码(它不依赖于方向):

public void AlignButtons(){
    llModules = (LinearLayout) findViewById(R.id.llModules);

    ViewTreeObserver viewTree = llModules.getViewTreeObserver();
    viewTree.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
        public boolean onPreDraw() {

            int childcount = llModules.getChildCount();
            int maxWidth = 0; //int maxHeight = 0;

            String fontPath = "fonts/Isabella-Decor.ttf";
            Typeface tf = Typeface.createFromAsset(getAssets(), fontPath);

            for (int i = 0; i < childcount; i++) {
                LinearLayout v = (LinearLayout)llModules.getChildAt(i);
                View vv = v.getChildAt(0);
                if (vv instanceof Button) {
                    int width = vv.getMeasuredWidth();
                    maxWidth = (maxWidth > width) ? maxWidth : width;
                    //int height = vv.getMeasuredHeight();
                    //maxHeight = (maxHeight > height) ? maxHeight : height;
                }
            }
            for (int i = 0; i < childcount; i++) {
                LinearLayout v = (LinearLayout)llModules.getChildAt(i);
                View vv = v.getChildAt(0);
                if (vv instanceof Button) {
                    LayoutParams params = ((Button) vv).getLayoutParams();
                    params.width = maxWidth;
                    //params.height = maxHeight;
                    ((Button) vv).setLayoutParams(params);

                    // Applying font
                    ((Button) vv).setTypeface(tf);
                }
                vv = v.getChildAt(1);
                if (vv instanceof TextView) {
                    // Applying font
                    ((TextView) vv).setTypeface(tf);
                }
            }

            return true;
        }
    });
}

Here, in my case:

在这里,在我的情况下:

llModule - some layout containing another layout with what we need to align(v.getChildAt(0);) and other(v.getChildAt(1);).

llModule - 包含另一个布局的布局,包含我们需要对齐的内容(v.getChildAt(0);)和其他布局(v.getChildAt(1);)。

LinearLayout v = (LinearLayout)llModules.getChildAt(i); - obtain layout of buttons to align.

LinearLayout v =(LinearLayout)llModules.getChildAt(i); - 获取要对齐的按钮布局。

Other parts are clear to understand.

其他部分很清楚。

Two cycles in this code are quite identical, but I still can't imagine how to combine them (to speed up the execution time).

这段代码中的两个循环完全相同,但我仍然无法想象如何组合它们(以加快执行时间)。

#5


0  

Use this proper code this will help you.

使用这个正确的代码,这将有助于你。

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:weightSum="3">

<Button
    android:id="@+id/button1"
    android:layout_width="0dp"
    android:layout_weight="1"
    android:layout_height="wrap_content"
    android:text="Get the Time"
    android:onClick="showNewDate" />
<Button
    android:id="@+id/button2"
    android:layout_width="0dp"
    android:layout_weight="1"
    android:layout_height="wrap_content"
    android:text="Get the Time"
    android:onClick="showNewDate" />
<Button
    android:id="@+id/button3"
    android:layout_width="0dp"
    android:layout_weight="1"
    android:layout_height="wrap_content"
    android:text="Get the Time"
    android:onClick="showNewDate" />

#6


-1  

Reading this thread, then doing some trial-and-error and noticed that android:layout_width="180px" is an accepted parameter. Now as said, I just stumbled on this, didn't try to use this to solve your three button scenario.

阅读这个帖子,然后做一些试错,并注意到android:layout_width =“180px”是一个可接受的参数。现在如上所述,我只是偶然发现了这一点,没有尝试使用它来解决你的三个按钮场景。

It could well be that things changed since you originally posted. Although I tried this while building for version 1.5. That's old enough... :-)

你最初发布的内容可能会发生变化。虽然我在为1.5版本构建时尝试了这个。那已经足够了...... :-)

Here is the complete main.xml:

这是完整的main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <TextView
        android:id="@+id/dateText"
        android:text="\n\nClick for Date\n\n"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/button"
        android:layout_width="180px"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="Get the Time"
        android:onClick="showNewDate" />

</LinearLayout>