【问题标题】:Android ConstraintLayout - Put one view on top of another viewAndroid ConstraintLayout - 将一个视图放在另一个视图之上
【发布时间】:2021-05-04 00:12:17
【问题描述】:

我正在尝试在Button 之上添加一个ProgressBar(两者都在ConstraintLayout 内)。

<Button
    android:id="@+id/sign_in_button"
    android:layout_width="280dp"
    android:layout_height="75dp"
    android:layout_marginBottom="75dp"
    android:layout_marginTop="50dp"
    android:text="@string/sign_in"
    android:textColor="@color/white"
    android:textSize="22sp"
    android:textStyle="bold"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/passwordEditText"
    app:layout_constraintVertical_bias="0.0"/>

<ProgressBar
    android:id="@+id/progressBar"
    style="?android:attr/progressBarStyle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintTop_toTopOf="@+id/sign_in_button"
    android:layout_marginTop="8dp"
    app:layout_constraintBottom_toBottomOf="@+id/sign_in_button"
    android:layout_marginBottom="8dp"
    app:layout_constraintVertical_bias="0.5"
    android:layout_marginLeft="8dp"
    app:layout_constraintLeft_toLeftOf="@+id/sign_in_button"
    android:layout_marginRight="8dp"
    app:layout_constraintRight_toRightOf="@+id/sign_in_button"/>

但即使在onCreate 中的ProgressBar 上调用bringToFront 之后,它也始终停留在Button 后面。

ProgressBar progressBar = (ProgressBar)findViewById(R.id.progressBar);
progressBar.bringToFront();

【问题讨论】:

  • 这太奇怪了,我试着玩一下你的布局,甚至颠倒了链条,这样进度条就限制在编辑文本上,按钮限制在进度条上,但按钮似乎始终位于进度条的顶部
  • 你可以使用 FrameLayout 吗?试一试,知道在 FrameLayout 中,z-index 是由布局内的顺序给出的(所以 Button 1st,Progress 2nd)
  • 你的密码编辑文本在哪里,因为我在没有应用程序的情况下检查了:layout_constraintTop_toBottomOf="@+id/passwordEditText" 我可以看到顶部的进度条你能提供密码编辑文本吗

标签: android android-layout android-constraintlayout


【解决方案1】:

ProgressBar上设置海拔; 2dp 似乎有效。

android:elevation="2dp"

您也可以尝试按照similar question 接受答案中的建议设置translationZ

我还遇到了this answer 作为替代方案。

【讨论】:

  • 但是elevationtranslationZ 仅适用于 API >=21,那么旧的 API 呢?
  • @q126y 我认为这在 API 21 之前不会成为问题,因此较旧的 API 不应该需要这个。我已经在运行 API 17 的模拟器上进行了尝试,进度条按预期显示在顶部。
  • @Cheticamp so 如何处理? AS 发出警告,它仅适用于 API 级别 21 及更高级别。
  • @q126y ViewCompat.setTranslationZ(view, 5)
  • ViewCompat.setElavation(view, 20f) 帮你
【解决方案2】:

我们需要使用 android:elevation 来控制它。

android:elevation="10dp"

此海拔属性仅适用于 API 级别 >= 21。但在低于该级别时,它将正常运行。如果我们在 Button 视图下方添加 Progress,它会显示位于另一个视图顶部底部的视图。

【讨论】:

    【解决方案3】:

    您可以简单地在应该出现在其下方的视图之后定义您想要的视图。

    对于按钮,请注意它们的高度由它们的 stateListAnimator 控制。 Widget.MaterialComponents.Button 的 stateListAnimator 的默认高度为 @dimen/mtrl_btn_elevation (2dp)。因此,如果您想在 Button 顶部显示视图,则它的高度至少应为 2dp。

    【讨论】:

    • 你如何确保 xml 会意外重新排列
    • @Cristan,最好提供代码 sn-p 或示例。谢谢
    • 我想知道为什么ProgressBar 不在Button 之上,即使ProgressBar 是在问题中的Button 之后定义的。
    • 我也认为这是真的,但无论我在约束布局排序中将图像视图放在哪里,它总是出现在按钮后面
    • 我终于明白了为什么这似乎不适用于按钮。我已经更新了我的答案以反映这一点。
    【解决方案4】:

    在约束布局中你应该使用

    翻译

    高于您想要低于的视图。

    【讨论】:

      【解决方案5】:

      虽然android:elevation="4dp"traslationz 可以工作,但是对于那个API 级别应该至少为21。如果由于某种原因你不能这样做,请确保在其他视图之后提到你想要的视图。例如,如果我想要在 ImageView 之上的 progressBar:

      <?xml version="1.0" encoding="utf-8"?>
      <androidx.constraintlayout.widget.ConstraintLayout 
         xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:app="http://schemas.android.com/apk/res-auto"
         xmlns:tools="http://schemas.android.com/tools"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         tools:context=".ImageActivity">
      
      <ImageView
         android:id="@+id/image_view"
         android:layout_width="0dp"
         android:layout_height="0dp"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintDimensionRatio="6:4"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent" />
      
      <ProgressBar
         android:id="@+id/progress_bar"
         style="?android:attr/progressBarStyle"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent" />
      </androidx.constraintlayout.widget.ConstraintLayout>
      

      【讨论】:

        【解决方案6】:

        使用海拔是有效的,但它有一些限制,比如它需要 api 级别 21+ 而且,如果海拔较低(在我的情况下是 2dp),那么在长按时视图变得不可见,因此您可以使用一个技巧,只需 将按钮替换为“View”或“TextView”,您可以做任何事情这些视图可以通过 buttonView 完成

        【讨论】:

          【解决方案7】:

          Android Sutdio 3.5 的更新答案:

          在更新后的布局编辑器中,现在可以更轻松地选择将哪个视图放在前面,如 Android Studio 发行说明中所示

          .. 此外,蓝色叠加层现在突出显示约束的目标。这个 当试图约束一个组件时,突出显示特别有用 与另一个重叠。

          https://developer.android.com/studio/releases

          更简单, 如果您向上拖动视图(复制粘贴或从布局编辑器中的组件树),它将获得较低的优先级(因此它将位于其他视图之后)

          【讨论】:

            【解决方案8】:

            按钮默认设置了 TranslationZ,因此您有两个选项

            1 - 使进度条 TranslationZ 大于按钮高度

            ViewCompat.setTranslationZ(progressBar, 5)// to support older api <21
            

            2 - 将按钮 TranslateZ 设为 0,以便视图在您的约束布局中按顺序显示在彼此之上,您可以通过将样式设置为按钮来实现此目的

            style="@style/Widget.AppCompat.Button.Borderless"
            

            【讨论】:

              【解决方案9】:

              您可以像下面这样包装它使用 framelayout 作为父级,并将 porogress bar 放在约束布局之外。这将重叠按钮

              <FrameLayout
                  android:layout_width="match_parent"
                  android:layout_height="match_parent">
              <androidx.constraintlayout.widget.ConstraintLayout
                      android:layout_width="match_parent"
                      android:layout_height="match_parent">
               //your all view inside it with button
               <Button/>......
                .........
               </androidx.constraintlayout.widget.ConstraintLayout>
              
               <ProgressBar
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"/>
              
              </FrameLayout>
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-04-18
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多