安卓5.0 - 无法在按钮上方显示进度条

36

我认为标题已经非常明确地阐述了我的问题... 这是我的布局:

            <RelativeLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">

                <Button
                    android:id="@+id/button_action"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="Login" />

                <ProgressBar
                    android:id="@+id/progress_bar"
                    android:layout_width="50dp"
                    android:layout_height="50dp"
                    android:layout_centerInParent="true"/>

            </RelativeLayout>

在Android SDK版本小于21的情况下,进度条正确地显示在按钮上并且居中于按钮内。但是在Android 5.0上,进度条显示按钮后面。

因此,当您在开发者选项设置中激活“显示布局边界”选项时,可以看到它被正确定位,但是如果没有该选项,则无法在屏幕上看到任何内容。

有人知道如何解决这个问题吗?我猜这是最近引入的高度问题,但我真的不知道该怎么处理。

编辑:

我还尝试了通过编程将setElevation(0)setTranslationY(0)应用于按钮,但仍未改变任何内容。因此,我想知道是否与高度有关。


你为什么不使用FrameLayout - Smileek
不,其实并没有。只是习惯问题吧。这会改变什么吗? - MathieuMaree
@ViewMa,好的。请看我的答案。 - Smileek
6个回答

92
你可以向ProgressBar中添加android:translationZ属性:
<ProgressBar
    android:id="@+id/progress_bar"
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:translationZ="2dp"
    android:layout_centerInParent="true"/>

1
感谢你的回答 wpiwonski,但是没有改变任何东西。 - MathieuMaree
2
很奇怪。我在模拟器上检查了代码,ProgressBar现在覆盖在Button上面。1 dp不够,但2 dp将ProgressBar移到了前面。 - wpiwonski
1
我的错误,我尝试将按钮的translationZ设置为0,而不是增加进度条的。确实有效,谢谢! - MathieuMaree
1
请注意,它的API版本为21或更高。 - krozaine
1
测试过 API 30,"2dp" 不可用,但是 "4dp" 可以! - inder_gt
显示剩余4条评论

13

我也遇到了同样的问题,我的简单“hack”是将Button包装到另一个FrameLayout中。 这样我就不需要关心API版本和其他高度问题了;)

这里出现了同样的问题,我的简单“hack”是将按钮包裹在另一个FrameLayout中。 这样我就不用担心API版本和其他高度问题了;)

<FrameLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center" >

        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
                <Button
                    android:id="@+id/button_action"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="Login" />
        </FrameLayout>

        <ProgressBar
            android:id="@+id/progress_bar"
            android:layout_width="50dp"
            android:layout_height="50dp" />
</FrameLayout>

7

这里有同样的问题,并且更好地解释了这个问题:

https://dev59.com/HV4d5IYBdhLWcg3wDvG1#27216368

引用 @CommonsWare 的话:

问题出现在 Android 5.0 的 elevation 属性上。显然,RelativeLayout 的 Z 轴排序与 elevation 相关。如果两个小部件具有相同的 elevation,那么 RelativeLayout 将决定它们的 Z 轴顺序。例如,如果您将布局更改为两个 Button 小部件,则可以看到这一点。但是,如果一个小部件(Button)有一个 elevation,而另一个小部件(ImageView)没有,那么 elevation 将优先。

您可以通过 android:stateListAnimator="@null" 或通过定义自己的自定义动画器来删除 Buttonelevation。或者,您可以向您的 ImageView 添加一些 elevation,以使其在 Z 轴上比 Button 更高。


虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面更改,仅有链接的答案可能会失效。 - Alex K

1

最好将android:translationZ设置为2dp以上。当您按下按钮时,您的视图/小部件将消失。我在这里解释了原因。

<!-- Elevation when button is pressed -->
<dimen name="button_elevation_material">1dp</dimen>
<!-- Z translation to apply when button is pressed -->
<dimen name="button_pressed_z_material">2dp</dimen>

按钮有这两个值,并在框架中定义。


0

默认情况下,如果您想在一个按钮上方显示一个视图,则该视图的高度至少应为2dp。

这是因为按钮的高度受其stateListAnimator控制。只要有一个,将高度设置为按钮本身不会做任何事情。 Widget.MaterialComponents.Button 的stateListAnimator具有默认高度 @dimen/mtrl_btn_elevation (2dp),因此必须考虑到该高度。

执行 android:stateListAnimator =“@null”也可以,但这将消除按钮上的任何阴影效果。


0
如果您在build.gradle中添加'androidx.core:core',则可以在API < 21上使用此代码:
ViewCompat.setTranslationZ(viewToElevate, 5);

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