Android ConstraintLayout - Coloque uma visão em cima de outra

105

Estou tentando adicionar um ProgressBarem cima de um Button(ambos estão dentro de um 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"/>

Mas mesmo depois de chamar bringToFronto ProgressBarin onCreate, ele sempre fica atrás do Button.

ProgressBar progressBar = (ProgressBar)findViewById(R.id.progressBar);
progressBar.bringToFront();
Adam Johns
fonte
isso é tão estranho, tentei brincar um pouco com o seu layout, até invertendo a cadeia para que a barra de progresso ficasse restrita ao texto de edição e o botão à barra de progresso mas o botão parecia estar sempre no topo da barra de progresso
lelloman
Você consegue usar um FrameLayout? Faça uma tentativa, sabendo que no FrameLayout, o z-index é dado pela ordem dentro do layout (então, Botão 1o, 2o Progresso)
razgraf
onde está seu passwordEditText como eu verifiquei sem app: layout_constraintTop_toBottomOf = "@ + id / passwordEditText" eu posso ver a barra de progresso no topo, você pode fornecer esse passwordEditText
Pavan

Respostas:

167

Defina uma elevação no ProgressBar; 2dpparece funcionar.

android:elevation="2dp"

Você também pode tentar definir translationZconforme sugerido na resposta aceita a uma pergunta semelhante .

Também encontrei esta resposta como alternativa.

Cheticamp
fonte
17
Mas elevatione translationZsão apenas para API> = 21, e as APIs mais antigas?
q126y
1
@ q126y Não acho que isso se tornou um problema até a API 21, então APIs mais antigas não deveriam precisar disso. Eu tentei em um emulador executando API 17 e a barra de progresso apareceu no topo conforme o esperado.
Cheticamp
@Cheticamp então como lidar com isso? O AS está avisando que funciona apenas com a API de nível 21 e superior.
Ajay S
6
@ q126yViewCompat.setTranslationZ(view, 5)
Silvia H
2
ViewCompat.setElavation(view, 20f)ajuda você
sagus_helgy
9

Precisamos usar android: elevation para controlar isso.

android:elevation="10dp"

Este atributo de elevação só funciona no nível de API> = 21. Mas abaixo disso ele se comportará normalmente. Se adicionarmos Progress abaixo da visualização do botão, ele mostrará a visualização que está na parte inferior na parte superior da outra visualização.

Ishan Fernando
fonte
6

Na maioria dos casos, você pode simplesmente definir a exibição que deseja no topo, depois daquela que deve aparecer abaixo dela.

Cristan
fonte
Como você garante que coz o xml pode acidentalmente ser reorganizado
RamPrasadBismil
@Cristan, é melhor fornecer um trecho de código ou um exemplo. Obrigado
blueware de
1
Eu me pergunto por que ProgressBarnão está no topo Button, embora ProgressBarseja definido depois Buttonna pergunta.
Michael Osofsky
Achei que isso fosse verdade também, mas não importa onde eu coloco uma visualização de imagem na ordem de layout de restrição, ela sempre aparece atrás de um botão
behelit
1

No layout de restrição, você deve usar

tradução

mais alto do que a visualização que você deseja abaixo.

Waqas Yousaf
fonte
0

Resposta atualizada para Android Sutdio 3.5:

No Layout Editor atualizado, agora é muito mais fácil escolher qual View estará na frente, conforme demonstrado nas notas de lançamento do Android Studio

.. Além disso, uma sobreposição azul agora destaca o destino da restrição. Esse destaque é particularmente útil ao tentar restringir a um componente que se sobrepõe a outro.

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

Ainda mais fácil, se você arrastar a Visualização para cima (copiar, colar ou da Árvore de Componentes no editor de layout), ela terá prioridade menor (por isso ficará atrás das outras visualizações)

Refael
fonte
0

Você pode envolvê-lo como a seguir. Use framelayout como pai e coloque a barra porogress fora do layout de restrição. Isso vai se sobrepor ao botão

<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>
Rohan Sharma
fonte
0

O botão por padrão tem TranslationZ definido, então você tem duas opções

1 - tornar a barra de progresso TranslationZ maior que a elevação do botão

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

2 - faça com que o botão TranslateZ seja 0 para que as visualizações apareçam acima umas das outras em ordem no seu Layout de restrição, você pode conseguir isso configurando o estilo para o botão

style="@style/Widget.AppCompat.Button.Borderless"
Mohammed Alaa
fonte
0

Embora android:elevation="4dp"ou traslationzfuncione, mas para esse nível de API deve ser pelo menos 21. Se por algum motivo você não puder fazer isso, certifique-se de que a exibição desejada no topo seja mencionada após as outras exibições. Por exemplo, se eu quiser progressBar sobre ImageView:

<?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>
Abhi
fonte