2011-11-08 5 views
7

Primero en mi experiencia: soy nuevo en Java viniendo de Ruby. Si eso ayuda¿Por qué los parámetros de diseño funcionan en la Programación de Android?

Estoy confundido acerca de cómo funcionan los parámetros de diseño. Estoy siguiendo una introducción básica de Hello World para crear una aplicación de Android. Paso 1, amplíe la clase de actividad y el método onCreate() para acceder al diseño XML. Ok, entiendo eso.

Luego creo un diseño (por ejemplo, un RelativeLayout) en Main.XML. Así que esto está haciendo uso de la clase RelativeLayout que extiende la clase ViewGroup, ok hasta ahora. Entonces digamos que creo un botón dentro de esto. Aquí es donde comienza mi pregunta. Si miro el ejemplo que estoy siguiendo, veo atributos asignados al botón que pertenece a la clase RelativeLayout (es decir: android: layout_alignParentRight = "true"). Estos parecen ser los params de diseño. Pero, ¿por qué funciona esto? La clase de botón parece heredar de la clase View. ¿Por qué un objeto de botón puede aceptar atributos para el objeto RelativeLayout? Tal vez mi programación de Ruby me está confundiendo ...

¡Gracias!

Actualización: Por posteridad: gracias a Slothsberry por señalar el enlace XML Layouts, que parece describir claramente la respuesta en 2 secciones en la sección de "Atributos" y en "Parámetros de diseño". La sección de atributos dice:

Todos los objetos View y ViewGroup admiten su propia variedad de atributos XML . Algunos atributos son específicos de un objeto View (para el ejemplo , TextView admite el atributo textSize), pero estos atributos también se heredan por cualquier objeto View que pueda ampliar esta clase . Algunos son comunes a todos los objetos de Vista, porque se heredan de la clase de vista de raíz (como el atributo id). Y, otros atributos se consideran "parámetros de diseño", que son los atributos que describen ciertas orientaciones de diseño del objeto Ver, como definido por el objeto ViewGroup principal de ese objeto.

La sección de parámetros de diseño es quizás la sección que realmente responde a esta pregunta. Donde dice:

Cada clase de ViewGroup implementa una clase anidada que extiende ViewGroup.LayoutParams. Esta subclase contiene tipos de propiedad que definen el tamaño y la posición para cada vista secundaria, según corresponda para el grupo de vista. Como se puede ver en la figura 1, el grupo de vista principal define los parámetros de diseño para cada vista secundaria (incluido el grupo de vista secundario).

Dan un buen diagrama también. Parece que un programador principiante necesita reconocer que, aunque se hace referencia a las clases de Java, el XML actúa más como una hoja de CSS y los atributos se computan primero de forma anidada antes de calcularse y trasladarse a sus contrapartes de la clase Java. Esa es mi comprensión actual de todos modos :)

+0

No, tienes razón en pensar que esto es extraño. He estado programando en Java durante más de 5 años, y esto es algo que cuando lo vi por primera vez no tenía sentido para mí. Todavía no estoy seguro de por qué funciona así. Esperemos que obtengamos una respuesta. –

+0

https://developer.android.com/reference/android/view/View.html#Layout – samosaris

Respuesta

6

Los parámetros de diseño no reflejan estrictamente la herencia de objetos (como habrá notado). La razón es que hay dos partes del diseño: configurar una vista y parametrizar el elemento primario de una vista usando esa vista como argumento.

Por lo tanto, parámetros como android: layout_below se ignorarán si el diseño principal no es un RelativeLayout. Podría tener sentido desde una perspectiva de OOP poner ese parámetro en el objeto RelativeLayout. Pero así es como lo harías en el código java.

En el código XML, se adopta el enfoque de que la información sobre el niño está contenida en el niño. los parámetros de diseño que requieren un elemento primario que no está presente se ignorarán cuando el diseño esté inflado. Es un buen sistema que usa Android para hacer que el XML sea más legible y portátil. Y no se refiere estrictamente a la estructura del paquete de clase, sino más bien a la forma intuitiva en que los humanos piensan de colocar las cosas en un diseño.

+0

Gracias, entendiste claramente mi error de comprensión y me diste una excelente respuesta. He agregado notas en mi pregunta para la posteridad basadas en algunas lecturas adicionales. Lo aprecio. – Inc1982

+1

Entender la "inflación" del diseño parece ser también una clave para comprender ... más lectura que encontré basada en su respuesta: http://www.androidguys.com/2008/07/09/inflation-is-a-good -thing/ – Inc1982

+0

Creo que las propias propiedades de diseño se heredan de una manera estricta, similar a la herencia de clase.Sin embargo, lo que Android hace con ellos parece variar, dependiendo de (al menos) el elemento principal. En general, desde que construye diseños desde la raíz hacia abajo (a menos que esté reutilizando includes, que tienen sus propias propiedades ya configuradas), puede simplemente ignorar las propiedades inapropiadas para sus elementos. Ni siquiera había notado que layout_below estaba disponible todo el tiempo, ya que nunca lo vi a menos que estuviera en RelativeLayout –

1

Estás un poco confundido, ese param de diseño no posee un objeto XML en particular. Si lo coloca en un niño XML XXXView o XXXLAyout, entenderá que su lado derecho debe estar en el mismo lugar que el derecho principal.

Entonces, si no crea los parámetros de diseño para ese niño, el niño trataría de heredar uno de sus padres.

+0

Gracias por la respuesta. Quizás puedas ayudarme a entender desde una perspectiva de Android/Java. Los objetos en Android tienen atributos, ¿sí? Supongo que todos los atributos tienen un objeto propietario, ¿sí? Cuando creo una etiqueta de botón, usted dice que no todos los atributos definidos dentro de la etiqueta de botón pertenecen al objeto de botón. ¿Es eso correcto? – Inc1982

+0

depende del lugar donde lo coloque. Debe pensar que el objeto en sí debe estar en otro contenedor. Entonces obedeces para decirle al objeto la posición relativa de su padre. Por supuesto, solo estamos hablando de diseño relativo. No es tan diferente de la programación CSS. Además, existe también otra etiqueta XML que le dice al niño cómo ordenar en el padre. El sistema es flexible para esas cosas. –

3

Todos los elementos de diseño en Android heredan de View, aunque muchos indirectamente.

La clase de vista genérica tiene propiedades (atributos) apropiadas para CUALQUIER elemento de diseño visible. para el diseño de la raíz, algunas propiedades como Gravedad del diseño, Dimensiones del diseño, etc. son establecidas por el sistema (en la mayoría de los casos, creo).

Si mi diseño de raíz es un diseño lineal, Android me permitirá tener un diseño relativo como un elemento secundario en la raíz. Android me permitirá establecer varias propiedades de diseño en el elemento anidado, para controlar cómo se renderiza. Esto funciona igual para Button y cualquier otro diseño de Android.

Si no le importa una propiedad en particular, no la configure. Están presentes para permitirle controlar las pantallas de su aplicación. Consulte XML Layouts o Hello Views para comenzar con los detalles.

+0

Gracias por agregar a la discusión. Si bien no pude asimilar el problema de su respuesta, su enlace a XML Layouts me dio lo que necesitaba. He actualizado mi pregunta anterior para incluir cómo he resuelto mi comprensión. Puedes avisarme si eso parece correcto. :) – Inc1982

0

Layout

diseño es un proceso de dos pasos: un paso de la medida y un pase de diseño. El pase de medición se implementa en measure(int, int) y es un recorrido descendente del árbol de vista. Cada vista empuja las especificaciones de dimensión hacia abajo del árbol durante la recursión. Al final del paso de la medida, cada vista ha almacenado sus medidas. El segundo pase ocurre en layout(int, int, int, int) y también es de arriba hacia abajo. Durante este pase, cada padre es responsable de colocar a todos sus hijos usando los tamaños calculados en el pase de la medida.

Cuando devuelve el método de una vista medida(), se deben establecer sus getMeasuredWidth() y getMeasuredHeight() valores, junto con las de todos los descendientes de ese punto de vista. El ancho medido de una vista y los valores de altura medidos deben respetar las restricciones impuestas por los padres de la vista. Esto garantiza que al final del pase de la medida, todos los padres acepten todas las medidas de sus hijos. Una vista principal puede llamar a measure() más de una vez en sus elementos secundarios. Por ejemplo, el padre puede medir a cada hijo una vez con dimensiones no especificadas para averiguar qué tan grande quiere ser, y luego volver a llamar a measure() con números reales si la suma de todos los tamaños no restringidos de los niños es demasiado grande o demasiado pequeña.

El paso de medida utiliza dos clases para comunicar las dimensiones. La clase View.MeasureSpec es utilizada por las vistas para decirles a sus padres cómo quieren ser medidos y posicionados. La clase base LayoutParams solo describe qué tan grande quiere ser la vista para ancho y alto.Para cada dimensión, se puede especificar uno de:

  • un número exacto
  • MATCH_PARENT, lo que significa el punto de vista quiere ser tan grande como su matriz (relleno menos)
  • WRAP_CONTENT, lo que significa que el view quiere ser lo suficientemente grande como para encerrar su contenido (más relleno).

Hay subclases de LayoutParams para diferentes subclases de ViewGroup. Por ejemplo, AbsoluteLayout tiene su propia subclase de LayoutParams que agrega un valor X e Y.

MeasureSpecs se utilizan para empujar hacia abajo el árbol requisitos de padres a hijos. A MeasureSpec puede estar en uno de tres modos:

  • por: Esto se usa por un padre para determinar la deseada dimensión de una vista niño. Por ejemplo, un LinearLayout puede llamar medida() en su hijo con la altura establecida en UNSPECIFIED y una anchura de exactamente 240 para averiguar la altura de la vista niño quiere ser dado una anchura de 240 píxeles.
  • exactamente: Esto es utilizado por el padre de imponer un tamaño exacto en el niño . El niño debe usar este tamaño y garantizar que todos sus descendientes se ajusten a este tamaño.
  • AT_MOST: Esto es utilizado por el padre de imponer un tamaño máximo en el niño . El niño debe garantizar que él y todos sus descendientes encajarán dentro de este tamaño.

Para iniciar un diseño, llaman requestLayout(). Este método es típicamente llamado por una vista en sí mismo cuando cree que ya no puede caber dentro de sus límites actuales.

Cuestiones relacionadas