什么是 ButtonBarLayout 以及我们应该如何使用它?

What is the ButtonBarLayout and how should we use it?

开发的时候意外发现了一个新的widget,名字叫android.support.v7.widget.ButtonBarLayout。我试图在互联网上搜索它,但没有找到任何东西,即使在官方开发文档站点上也是如此。

同时,我在Android Studio里到处搜索ButtonBarLayout,发现有两个ButtonBarLayout,一个是android.support.v7.widget.ButtonBarLayout,另一个是com.android.internal.widget.ButtonBarLayout。我试图阅读两者的源代码,我发现它们除了包名外是相同的。所以我想也许 android.support.v7.widget.ButtonBarLayout 来自 com.android.internal.widget.ButtonBarLayout 内部 ButtonBarLayout 通过测试并发布之后。同时,ButtonBarLayout继承自LinearLayout

但是有一些问题:

有人知道 ButtonBarLayout 吗?

P.S.: 我使用 Android Studio of 2.0.0 Preview 4 and Gradle 2.0.0-alpha3 的插件Android 支持库 23.1.1 and Platform-tools of 23.1 and Build-tools 23.0.2.

https://android.googlesource.com/platform/frameworks/base/+/master/core/java/com/android/internal/widget/ButtonBarLayout.java

查看代码,我认为它是用于按钮的 LinearLayout (duh)。您可以将其视为被垂直分隔符分隔的对话框按钮:| . AllowStacking 会将方向更改为垂直,并将重力更改为右侧而不是底部。我应该尝试一下才能给出更好的答案

首先你是对的。 ButtonBar 布局在官方 Android 文档中似乎没有任何特色。我试着自己搜索它,但无济于事。但是我发现了一些信息,这些信息定义了什么是 ButtonBar 布局以及何时使用它。希望这对你有所帮助。

大多数教程在对话框或屏幕底部使用 Buttonbar 布局来确认或拒绝选项。下图是 ButtonBar 布局如何在屏幕中使用的直观表示。

上面的屏幕截图具有以下布局xml:

<LinearLayout
    style="?android:attr/buttonBarStyle"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

    <Button
        android:id="@+id/Button01"
        style="?android:attr/buttonBarButtonStyle"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Show" />

    <Button
        android:id="@+id/Button02"
        style="?android:attr/buttonBarButtonStyle"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Change" />
</LinearLayout>

<EditText
    android:id="@+id/myView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:ems="10" >

    <requestFocus />
</EditText>

所以基本上 Android 在这里所做的只是在 LinearLayout 中创建两个彼此相邻的按钮,每个按钮的 match_parent 参数设置为宽度。因此每个按钮占据屏幕大小的一半。 Android 实际上已经消除了创建单独按钮并正确定位它们以适应不同屏幕的麻烦,方法是创建一个简单的小部件来处理这个问题。

与支持库一样,Android 已经为使用早期 API 的开发人员实施了此功能。他们为此使用支持库是正常的。

希望这对您有所帮助:)

source codeButtonBarLayout的描述如下:

/**
 * An extension of LinearLayout that automatically switches to vertical
 * orientation when it can't fit its child views horizontally.
 */

因此,从本质上讲,它只不过是一个智能 LinearLayout,它根据屏幕上可用的 space 来管理 auto-switching 方向。

同一个ButtonBarLayout.java文件在评论中描述mAllowStacking如下:

/** Whether the current configuration allows stacking. */

Source Code Here

正如其他人指出的那样,class 描述准确地说明了它是什么:an extension of LinearLayout that automatically switches to vertical orientation when it can't fit its child views horizontally.

我可能会补充说,这样做显然是为了适应 material design specifications 关于对话框的要求。它们区分 并排 按钮和 堆叠 按钮。参见示例:

Side-by-side buttons are recommended when the text of each label does not exceed the maximum button width, such as the commonly used OK/Cancel buttons.

当单个按钮太大或没有足够的空间容纳两个按钮时,您应该使用堆叠按钮:

When text labels exceed the maximum button width, use stacked buttons to accommodate the text. Affirmative actions are stacked above dismissive actions.

因此,此 class 的一种可能用途是设计您自己的对话框。例如,AlertDialogAlertDialog.Builder 为带按钮的对话框提供内部支持,但有时您只想子class DialogFragmentAppCompatDialogFragment 以获得更好的控制。

在那里,设置一个遵循设计指南的底部按钮栏并完全控制按钮(例如启用和禁用,AlertDialog AFAIK 无法做到的事情可能会很有用).

ButtonBarlayout 在官方 Android 文档中没有任何特色。 它用于根据 space.

自动切换方向

关于您的问题:
我们应该如何使用它?

我猜它还没有被记录下来,因为它还不稳定。
它突然出现是因为这个长期存在的投诉源于设备供应商对 ROM 的修改不当。
https://code.google.com/p/android/issues/detail?id=78377

有关类路径的解决方案以及为什么 .internal. 中的所有 类 都被设为 public,请参阅 #270。 不,即使修复了很多因 ROM 修改不当而导致的错误仍然存​​在(在许多知名品牌的设备中)。该问题很快被项目成员拒绝。

我认为在文档出现之前我们不应该使用它。
不过只是我的 $.02。

只是为了补充其他答案,如果你们想检查 ButtonBarLayout 的方向,您应该在测量值调用后检查方向。

换句话说(Kotlin):

buttonBarLayout.post {
    val orientation = buttonBarLayout.orientation
    val height = buttonBarLayout.measuredHeight
}