¿Cómo mostrar un diseño encima del otro mediante programación en mi caso?

84

Mi diseño principal main.xml simplemente contiene dos LinearLayouts:

  • La primera LinearLayout alberga a VideoViewy a Button,
  • El segundo LinearLayoutaloja un EditText, y esto LinearLayoutha establecido el valor de visibilidad en " GONE " ( android:visibility="gone")

como abajo:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    
    android:layout_height="fill_parent" 
    android:layout_width="fill_parent"
        android:orientation="vertical"
>
    <LinearLayout 
        android:id="@+id/first_ll"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"

    >
        <VideoView 
            android:id="@+id/my_video"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="9"
        />

        <Button
            android:id="@+id/my_btn"
            android:layout_width="30dip" 
            android:layout_height="30dip"
            android:layout_gravity="right|bottom"
                android:layout_weight="1"
        />

    </LinearLayout>

    <LinearLayout 
        android:id="@+id/second_ll"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingTop="2dip"

        android:visibility="gone"
    >
        <EditText 
            android:id="@+id/edit_text_field"
            android:layout_height="40dip"
            android:layout_width="fill_parent"
            android:layout_weight="5"
            android:layout_gravity="center_vertical"
        />

    </LinearLayout>
</LinearLayout>

He implementado con éxito la característica de que cuando el Button(con my_btn id) es presionado, el segundo LinearLayout con EditTextse muestra el campo, con el siguiente código de Java:

LinearLayout secondLL = (LinearLayout) findViewById(R.id.second_ll);

Button myBtn = (Button) findViewById(R.id.my_btn);
myBtn.setOnClickListener(new OnClickListener(){
    @Override
    public void onClick(View v){
        int visibility = secondLL.getVisibility();

        if(visibility==View.GONE)
            secondLL.setVisibility(View.VISIBLE);

    }
}); 

Con el código Java anterior, el segundo LinearLayout con EditTextse muestra como anexando debajo del primero, lo LinearLayout que tiene sentido.

PERO , Lo que necesito es: cuando Buttonse pulse (id my_btn), la segunda LinearLayout con la EditText que se muestra en la parte superior de la primera LinearLayout , que se parece a la segunda LinearLayout con la EditTextque se levanta de la parte inferior de la pantalla, y el segundo LinearLayout conEditText sólo ocupan parte de la pantalla desde abajo, ese es el primer LinearLayout aún visible, como se muestra en la imagen de abajo:

ingrese la descripción de la imagen aquí

Así que, cuando Buttonse pulsa: (id my_btn) para mostrar la forma en la segunda LinearLayout con EditText en la parte superior de la primera LinearLayout en lugar de añadir segundo LinearLayout continuación primero LinearLayout mediante programación?

Mellon
fuente

Respuestas:

187

Utilice un FrameLayout con dos hijos. Los dos niños se superpondrán. Esto se recomienda en uno de los tutoriales de Android en realidad, no es un truco ...

Aquí hay un ejemplo en el que se muestra un TextView encima de un ImageView:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">

  <ImageView  
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 

    android:scaleType="center"
    android:src="@drawable/golden_gate" />

  <TextView
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_marginBottom="20dip"
    android:layout_gravity="center_horizontal|bottom"

    android:padding="12dip"

    android:background="#AA000000"
    android:textColor="#ffffffff"

    android:text="Golden Gate" />

</FrameLayout>

Aqui esta el resultado

Alexandru Cristescu
fuente
13
En este código, ¿qué hace que esté TextViewarriba? ¿Es porque ocupa el segundo lugar en la lista?
Adam Johns
13
Como dicen los documentos de FrameLayout: Las vistas secundarias se dibujan en una pila, con la secundaria agregada más recientemente en la parte superior. Teniendo en cuenta que el diseño xml se analiza de arriba a abajo, el elemento TextView se dibuja en la parte superior como el último en el xml.
Maciej Pigulski
Estoy intentando esto, pero con Scrollview como primer hijo de FrameLayout y TextView como segundo hijo. Pero aquí no muestra la vista de desplazamiento en el fondo. Alguna ayuda.
Raju
1
¡Gracias hermano! ¡Esta respuesta fue exactamente lo que estoy buscando! ¡Excelente! @Raju: Coloque el siguiente FrameLayout antes de la ÚLTIMA etiqueta de cierre de su diseño (pantalla completa) ... <FrameLayout android: id = "@ + id / icon_frame_container" android: layout_width = "match_parent" android: layout_height = "match_parent"> </FrameLayout> Ahora haga referencia a él y haga su método onClick o onTouch como de costumbre.
Martin Pfeffer
1
FrameLayout es la elección correcta aquí, pero también vale la pena señalar que RelativeLayout se comportaría de la misma manera al tener las vistas secundarias apiladas una encima de la otra a medida que se agregan. (Era nuevo en Android y pensé erróneamente que solo FrameLayout podría lograr el apilamiento después de leer esta respuesta. Vaya)
Luke
5

FrameLayout no es la mejor manera de hacer esto:

Úselo en su RelativeLayoutlugar. Puede colocar los elementos en cualquier lugar que desee. El elemento que viene después, tiene el índice z más alto que el anterior (es decir, supera al anterior).

Ejemplo:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent" android:layout_height="match_parent">
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorPrimary"
        app:srcCompat="@drawable/ic_information"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is a text."
        android:layout_centerHorizontal="true"
        android:layout_alignParentBottom="true"
        android:layout_margin="8dp"
        android:padding="5dp"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:background="#A000"
        android:textColor="@android:color/white"/>
</RelativeLayout>

ingrese la descripción de la imagen aquí

Raj Yadav
fuente
4

La respuesta, dada por Alexandru, funciona bastante bien. Como dijo, es importante que esta vista de "acceso" se agregue como último elemento. Aquí hay un código que me sirvió:

        ...

        ...

            </LinearLayout>

        </LinearLayout>

    </FrameLayout>

</LinearLayout>

<!-- place a FrameLayout (match_parent) as the last child -->
<FrameLayout
    android:id="@+id/icon_frame_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</FrameLayout>

</TabHost>

en Java:

final MaterialDialog materialDialog = (MaterialDialog) dialogInterface;

FrameLayout frameLayout = (FrameLayout) materialDialog
        .findViewById(R.id.icon_frame_container);

frameLayout.setOnTouchListener(
        new OnSwipeTouchListener(ShowCardActivity.this) {
Martin Pfeffer
fuente