¿Por qué la gravedad no funciona cuando se aplica al diseño relativo?
Ya entiendo que si uso layout_gravity="center_horizontal"
en la vista de texto, entonces el texto será center. Pero no quiero usarlo porque quiero tener el menor código posible y la mejor manera de hacerlo es aplicando gravity="center_horizontal"
a mi diseño relativo. También estoy haciendo esta pregunta porque me preocupa incluso el uso de gravity
o layout_gravity
con diseños relativos en absoluto. Como al hacer mi investigación encontré esta respuesta.
Observe la parte que dice:
- Trunca automáticamente texto TextView para no superponer otro TextView
- Error: Los tipos de cadena no están permitidos (en 'layout_height' con el valor 'wrap content'). activity_main.xml
- Intención de Fragmento a Actividad
- ¿Debería estar lleno el archivo xml del contenido de la copia de seguridad completa o no incluirlo en todos?
- RadioGroup checkedButton propiedad
No utilice gravity / layout_gravity con un RelativeLayout. Utilícelos para vistas en LinearLayouts y FrameLayouts.
A pesar de que parece bastante evidente para mí de la distribución relativa de la documentación de Android , que claramente la gravity
lista como un atributo válido, que Google pretendía que estos atributos para ser utilizado con disposiciones relativas.
Si esa cita es correcta, ¿cómo centrar las vistas en diseños relativos?
También, aquí está mi código:
Observe que el título no está centrado horizontalmente
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:gravity="center_horizontal" tools:context="com.something"> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.AppCompat.Title" android:textAlignment="center" android:text="@string/app_title" android:layout_marginBottom="@dimen/main_spacing" android:textSize="24sp" /> <AutoCompleteTextView android:id="@+id/enterContact" android:text="Enter Contact" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAlignment="center" android:layout_below="@+id/title" android:layout_marginBottom="@dimen/main_spacing" /> </RelativeLayout>
- Android - No se puede resolver el símbolo "R"
- La biblioteca appcompat importada tiene errores
- Los caracteres especiales no se muestran en android
- Disposición de Android: vistas cuadráticas
- Actividad de configuración botón Arriba
- Android PdfDocument dañado cuando se guarda en un almacenamiento externo
- Cómo cambiar el color de entrada del imput en xml?
- ¿Cómo establezco el estado de clic para mi botón personalizado?
Esta es una respuesta suplementaria a Gravity y layout_gravity en Android .
Ver la gravity
y layout_gravity
dentro de un diseño relativo
Mi declaración original de que gravity
y gravity
layout_gravity
no debería usarse en las subcarpetas de un RelativeLayout
era en parte incorrecta. La gravity
realmente funciona bien. Sin embargo, layout_gravity
no tiene efecto. Esto se puede ver en el siguiente ejemplo. El verde claro y azul claro son TextViews. Los otros dos colores de fondo son RelativeLayouts.
Como puedes ver, la gravity
funciona, pero layout_gravity
no funciona.
Disposición relativa con gravity
Mi respuesta original sobre gravity
y layout_gravity
trató con estos atributos que se aplicaban a las vistas dentro de un ViewGroup
(específicamente un LinearLayout
), no al propio ViewGroup
. Sin embargo, es posible establecer gravity
y layout_gravity
en un RelativeLayout
. El layout_gravity
afectaría cómo el RelativeLayout
se posiciona dentro de su propio padre, así que no trataré de eso aquí. La forma en que la gravity
afecta a las sub-vistas, sin embargo, se muestra en la imagen de abajo.
Redimensioné el ancho de todos los subviews para que lo que está sucediendo es más claro. Tenga en cuenta que la manera en que RelativeLayout
maneja la gravedad es tomar todas las subviews como un grupo y moverlas alrededor del diseño. Esto significa que cualquiera que sea la vista más amplia determinará cómo se posiciona todo lo demás. Así que la gravedad en un diseño Relativo probablemente sólo sea útil si todas las sub-vistas tienen el mismo ancho.
Disposición lineal con gravity
Cuando agrega gravity
a un LinearLayout
, organiza las subviews como se esperaría. Por ejemplo, se podría "guardar código" estableciendo la gravity
de LinearLayout
a center_horizontally
. De esta manera no hay necesidad de configurar individualmente la layout_gravity
de layout_gravity
de cada subvista. Vea las diferentes opciones en la imagen de abajo.
Tenga en cuenta que cuando una vista utiliza layout_gravity
, anula la gravedad de LinearLayout. (Esto se puede ver en el título de los dos diseños en la imagen de la izquierda.La gravity
LinearLayout se estableció a la left
y la right
, pero el título TextView layout_gravity
se estableció en center_horizontally
).
Notas finales
Al posicionar vistas dentro de un RelativeLayout , la manera general de hacerlo es agregar cosas como las siguientes a cada vista:
-
layout_alignParentTop
-
layout_centerVertical
-
layout_below
-
layout_toRightOf
Si uno quiere establecer todas las vistas a la vez, un LinearLayout
probablemente sería mejor (o tal vez con un estilo).
Así que para resumir,
- El
layout_gravity
no funciona para subviews en un RelativeLayout. - La
gravity
de un RelativeLayout funciona, pero no como uno podría esperar.
XML suplementario
XML para la imagen "Ver gravity
y layout_gravity
dentro de un diseño relativo" :
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:background="#e3e2ad" > <TextView android:id="@+id/tvTop1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:textSize="24sp" android:text="Views' gravity=" /> <!-- examples of gravity --> <TextView android:id="@+id/tvTop2" android:layout_below="@id/tvTop1" android:layout_width="200dp" android:layout_height="40dp" android:background="#bcf5b1" android:gravity="left" android:text="left" /> <TextView android:id="@+id/tvTop3" android:layout_below="@id/tvTop2" android:layout_width="200dp" android:layout_height="40dp" android:background="#aacaff" android:gravity="center_horizontal" android:text="center_horizontal" /> <TextView android:id="@+id/tvTop4" android:layout_below="@id/tvTop3" android:layout_width="200dp" android:layout_height="40dp" android:background="#bcf5b1" android:gravity="right" android:text="right" /> <TextView android:id="@+id/tvTop5" android:layout_below="@id/tvTop4" android:layout_width="200dp" android:layout_height="40dp" android:background="#aacaff" android:gravity="center" android:text="center" /> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:background="#d6c6cd" > <TextView android:id="@+id/tvBottom1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:textSize="24sp" android:text="Views' layout_gravity=" /> <!-- examples of layout_gravity --> <TextView android:id="@+id/tvBottom2" android:layout_below="@id/tvBottom1" android:layout_width="200dp" android:layout_height="40dp" android:layout_gravity="left" android:background="#bcf5b1" android:text="left" /> <TextView android:id="@+id/tvBottom3" android:layout_below="@id/tvBottom2" android:layout_width="200dp" android:layout_height="40dp" android:layout_gravity="center_horizontal" android:background="#aacaff" android:text="center_horizontal" /> <TextView android:id="@+id/tvBottom4" android:layout_below="@id/tvBottom3" android:layout_width="200dp" android:layout_height="40dp" android:layout_gravity="right" android:background="#bcf5b1" android:text="right" /> <TextView android:id="@+id/tvBottom5" android:layout_below="@id/tvBottom4" android:layout_width="200dp" android:layout_height="40dp" android:layout_gravity="center" android:background="#aacaff" android:text="center" /> </RelativeLayout> </LinearLayout>
XML para la imagen "Disposición relativa con gravedad" :
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center_horizontal" android:background="#e3e2ad" > <TextView android:id="@+id/tvTop1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="24sp" android:text="Views' gravity=" /> <!-- examples of gravity --> <TextView android:id="@+id/tvTop2" android:layout_below="@id/tvTop1" android:layout_width="200dp" android:layout_height="40dp" android:background="#bcf5b1" android:gravity="left" android:text="left" /> <TextView android:id="@+id/tvTop3" android:layout_below="@id/tvTop2" android:layout_width="300dp" android:layout_height="40dp" android:background="#aacaff" android:gravity="center_horizontal" android:text="center_horizontal" /> <TextView android:id="@+id/tvTop4" android:layout_below="@id/tvTop3" android:layout_width="100dp" android:layout_height="40dp" android:background="#bcf5b1" android:gravity="right" android:text="right" /> <TextView android:id="@+id/tvTop5" android:layout_below="@id/tvTop4" android:layout_width="150dp" android:layout_height="40dp" android:background="#aacaff" android:gravity="center" android:text="center" /> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:background="#d6c6cd" > <TextView android:id="@+id/tvBottom1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="24sp" android:text="Views' gravity=" /> <!-- examples of layout_gravity --> <TextView android:id="@+id/tvBottom2" android:layout_below="@id/tvBottom1" android:layout_width="200dp" android:layout_height="40dp" android:gravity="left" android:background="#bcf5b1" android:text="left" /> <TextView android:id="@+id/tvBottom3" android:layout_below="@id/tvBottom2" android:layout_width="300dp" android:layout_height="40dp" android:gravity="center_horizontal" android:background="#aacaff" android:text="center_horizontal" /> <TextView android:id="@+id/tvBottom4" android:layout_below="@id/tvBottom3" android:layout_width="100dp" android:layout_height="40dp" android:gravity="right" android:background="#bcf5b1" android:text="right" /> <TextView android:id="@+id/tvBottom5" android:layout_below="@id/tvBottom4" android:layout_width="150dp" android:layout_height="40dp" android:gravity="center" android:background="#aacaff" android:text="center" /> </RelativeLayout> </LinearLayout>
XML para la imagen "Linear Layout con gravedad" :
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center_horizontal" android:background="#e3e2ad" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:textSize="24sp" android:text="View's gravity=" /> <TextView android:layout_width="200dp" android:layout_height="40dp" android:background="#bcf5b1" android:gravity="left" android:text="left" /> <TextView android:layout_width="300dp" android:layout_height="40dp" android:background="#aacaff" android:gravity="center_horizontal" android:text="center_horizontal" /> <TextView android:layout_width="100dp" android:layout_height="40dp" android:background="#bcf5b1" android:gravity="right" android:text="right" /> <TextView android:layout_width="150dp" android:layout_height="40dp" android:background="#aacaff" android:gravity="center" android:text="center" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:background="#d6c6cd" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:textSize="24sp" android:text="View's gravity=" /> <TextView android:layout_width="200dp" android:layout_height="40dp" android:background="#bcf5b1" android:gravity="left" android:text="left" /> <TextView android:layout_width="300dp" android:layout_height="40dp" android:background="#aacaff" android:gravity="center_horizontal" android:text="center_horizontal" /> <TextView android:layout_width="100dp" android:layout_height="40dp" android:background="#bcf5b1" android:gravity="right" android:text="right" /> <TextView android:layout_width="150dp" android:layout_height="40dp" android:background="#aacaff" android:gravity="center" android:text="center" /> </LinearLayout> </LinearLayout>
Comprobación de su diseño, para mí está funcionando (el TextView
está centrado correctamente).
Sin embargo, también puedes eliminar android:gravity="center_horizontal"
de RelativeLayout
y añadir android:layout_centerHorizontal="true"
en TextView
.
Siempre he tenido problemas con RelativeLayouts y TextViews también. Creo que esto se debe al hecho de que TextView calcula su tamaño dinámicamente y esto evita que funcione bien con la gravedad del diseño. Esa es sólo una de mis suposiciones. La solución que generalmente adopto es configurar un tamaño horizontal textview con match_parent. Puede ser una solución subóptima, pero debería funcionar. En caso de que necesite un textView de tamaño fijo, puede poner una dimensión de tamaño fijo y debería funcionar también, sólo da problemas con wrap_content.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:gravity="center_horizontal" tools:context="com.something"> <TextView android:id="@+id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.AppCompat.Title" android:textAlignment="center" android:text="@string/app_title" android:layout_marginBottom="@dimen/main_spacing" android:textSize="24sp" /> </RelativeLayout>
Edit: como sugiere @Valentino S., añadiendo
android:layout_centerHorizontal="true"
con wrap_content debería funcionar también. La razón es en mi cabeza sigue siendo el mismo: tamaño de textView se calcula más tarde.
Como dice la documentación :
androide: gravedad
Especifica cómo un objeto debe posicionar su contenido, tanto en los ejes X como Y, dentro de sus propios límites.
…
center_horizontal
Coloque el objeto en el centro horizontal de su contenedor, sin cambiar su tamaño.
Por lo tanto, el android:gravity="center_horizontal"
se centrará horizontalmente, relacionando RelativeLayout a su padre. No hacer su centro de contenido horizontal.
Recuerde que android:layout_gravity
se utiliza para la propia vista en relación con el padre o el diseño.
Tenga en cuenta que el comportamiento de Layout puede variar ligeramente para cada nivel de API. Y tenga en cuenta, que no podemos 100% seguro de que el resultado visual en el Editor de diseño es correcto. Siempre pruebe su diseño en dispositivos reales.
prueba esto:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:background="#000000" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin"> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_marginBottom="10dp" android:background="#ffffffff" android:text="TITLE" android:textAlignment="center" android:textAppearance="@style/TextAppearance.AppCompat.Title" android:textSize="24sp" /> <AutoCompleteTextView android:id="@+id/enterContact" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/title" android:layout_marginBottom="10dp" android:background="#ffffffff" android:text="Enter Contact" android:textAlignment="center" /> </RelativeLayout>
TlDr: android: gravity Trabaja con RelativeLayout, puedes saltar a la parte inferior si no quieres leer la explicación
EDITAR esta es una pared gigante de texto, por favor, tenga paciencia conmigo
Esto es lo que imagino que quieres lograr:
<TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.AppCompat.Title" android:textAlignment="center" android:text="@string/app_title" android:layout_marginBottom="@dimen/main_spacing" android:textSize="24sp" android:layout_centerHorizontal="true"/> <!-- LAYOUT PARAMS WORK!!!-->
¿Por qué este trabajo, mientras que el android:gravity
( aparentemente ) no?
-
si su objetivo es poner el TextView en el centro horizontal de la Layout / Pantalla que tiene que dejar que el
RelativeLayout
saber! -
esto se logra a través de algo llamado
LayoutParams
– son estructuras de datos definidas por cadaView
que son utilizadas por el padre de View (en este caso, el RelativeLayout) -
así que digamos que su
TextView
tiene el siguienteLayoutParams
:androide: layout_centerHorizontal = "true"
Obtendrá algo como esto:
Cuando RelativeLayout
está distribuyendo sus vistas secundarias alrededor de la pantalla, a lo largo del camino hay un método callback que se ejecuta – onLayout (…) – que es parte de una secuencia de método más complejo que determinará la posición de cada niño. RelativeLayout , esto se logra en parte mediante el acceso a LayoutParams
en cada View
secundaria, en este caso esa línea en su TextView
- Es por eso que decimos LayoutParams se pasan a los padres como en el enlace que mencionó antes
ADVERTENCIA : ¡Fuente de confusión sin fin!
Ver posicionamiento dentro de Layout
s / ViewGroup
s se realiza a través de LayoutParam
s las llamadas onLayout
Sucede que algunos diseños como FrameLayout
tienen un LayoutParam llamado android: layout_gravity que causa una gran confusión con la propiedad android:gravity
que cada vista puede definir, que NO es la misma y ni siquiera un LayoutParam
android:gravity
es utilizada por cualquier View (como un TextView
por ejemplo) para colocar su contenido dentro.
Ejemplo: digamos que usted cambia su TextView a ser muy alto , y desea que el texto en la parte inferior de la TextView, en lugar de en la parte superior
<TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="95dp" <------------ very high! android:textAppearance="@style/TextAppearance.AppCompat.Title" android:textAlignment="center" android:text="@string/app_title" android:layout_marginBottom="@dimen/main_spacing" android:textSize="24sp" android:layout_centerHorizontal="true" <----- LayoutParams for RelativeLayout />
TextView está CENTRADO en RelativeLayout pero el texto está en la parte superior de la "caja"
TextView
android: gravedad para administrar la posición de texto DENTRO DEL TextView
<TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="95dp" android:textAppearance="@style/TextAppearance.AppCompat.Title" android:textAlignment="center" android:text="@string/app_title" android:layout_marginBottom="@dimen/main_spacing" android:textSize="24sp" android:layout_centerHorizontal="true" android:gravity="bottom" <---**NOT LayoutParams**, NOT passed to RLayout />
Resultado: Como se esperaba sólo el interior de la vista cambió
TLDR Ahora, si quieres ignorar todo lo anterior y seguir usando android: gravity con RelativeLayout, RelativeLayout
también es una View
por lo que tiene la propiedad android: gravity, pero tienes que eliminar otras propiedades o LayoutParams que anularán el comportamiento definido por el android : aspecto de la gravedad en android: gravedad en el trabajo con RelativeLayout
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:gravity="bottom"> <!-- NOT LAYOUT PARAMS --> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="95dp" android:textAppearance="@style/TextAppearance.AppCompat.Title" android:textAlignment="center" android:text="@string/app_title" android:layout_marginBottom="@dimen/main_spacing" android:textSize="24sp" android:layout_centerHorizontal="true" /> <AutoCompleteTextView android:id="@+id/enterContact" android:text="Enter Contact" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAlignment="center" android:layout_below="@+id/title" android:layout_marginBottom="@dimen/main_spacing" /> </RelativeLayout>
- Android con Smack -¿Cómo obtener la lista de usuarios en línea?
- ¿Cómo eliminar la barra de acción azul en Android?