titulo studio programacion personalizar icono editar color cambiar bar agregar android resize custom-view

android - studio - Cambiar el tamaño del botón personalizado para diseños y contenedores



menu toolbar android (2)

Tengo una clase personalizada (botón táctil) que extiende la clase TextView. Tengo problemas para cambiar el tamaño del botón manualmente. Puedo hacer que el botón funcione solo para un tipo de diseño o contenedor, pero no para ambos. En su mayor parte, el botón táctil está en vistas de cuadrícula, por lo que mi método para cambiar el tamaño es el siguiente:

private void setLayout(buttonsize_t size) { log("Setting Layout: "+buttonsize_t.getPxl(size)); final float scale = getContext().getResources().getDisplayMetrics().density; int dim = (int) (buttonsize_t.getPxl(size) * scale + 0.5f); AbsListView.LayoutParams params = (AbsListView.LayoutParams) getLayoutParams(); if (params != null) { params.height = dim; params.width = dim; } else { params = new AbsListView.LayoutParams(dim,dim); } setLayoutParams(params); }

Sin embargo, cuando se cambia el tamaño del TouchButton en LinearLayout (por ejemplo), recibo un bloqueo con el Logcat:

09-01 19:18:35.630: ERROR/AndroidRuntime(20793): java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams 09-01 19:18:35.630: ERROR/AndroidRuntime(20793): at com.ians.aac3.TouchButton.setLayout(TouchButton.java:204)

La línea 204 se refiere a la instanciación de params.

Noté que tanto GridView como LinearLayout comparten el ViewGroup padre, así que intenté usar ViewGroup.LayoutParams . Esto, sin embargo, esto conducirá al mismo comportamiento para las vistas de malla (logcat citando la misma línea).

¿Alguien sabe cómo puedo hacer que esto funcione para cualquier tipo de diseño o artilugio?

ACTUALIZACIÓN: Como lo recomiendo intenté con el grupo Ver nuevamente:

import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; import android.util.Log; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.widget.TextView; ..... ViewGroup.LayoutParams params = getLayoutParams(); if (params != null) { params.height = dim; params.width = dim; } else { params = new LayoutParams(dim,dim); } setLayoutParams(params);

o sin tratar de reciclar los layoutparams actuales:

setLayoutParams(new ViewGroup.LayoutParams(dim, dim));

Y obtengo el mismo tipo de error:

09-02 09:10:49.680: ERROR/AndroidRuntime(7069): java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams 09-02 09:10:49.680: ERROR/AndroidRuntime(7069): at android.widget.GridView.onMeasure(GridView.java:1028) 09-02 09:10:49.680: ERROR/AndroidRuntime(7069): at android.view.View.measure(View.java:10828) 09-02 09:10:49.680: ERROR/AndroidRuntime(7069): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4351) 09-02 09:10:49.680: ERROR/AndroidRuntime(7069): at android.widget.FrameLayout.onMeasure(FrameLayout.java:267) 09-02 09:10:49.680: ERROR/AndroidRuntime(7069): at android.view.View.measure(View.java:10828) 09-02 09:10:49.680: ERROR/AndroidRuntime(7069): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4351) 09-02 09:10:49.680: ERROR/AndroidRuntime(7069): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1284)

Actualización 2: parece que el uso de ViewGroup.LayoutParams especificado anteriormente funciona para LinearLayout. Sin embargo, como se vio anteriormente, a la vista de cuadrícula no le gusta ...


¿Por qué estás lanzando LayoutParams en absoluto?

Button.getLayoutParams() debería devolver ViewGroup.LayoutParams , que puede acceder al alto y ancho sin necesidad de ViewGroup.LayoutParams . ¿Estás seguro de que cuando ViewGroup.LayoutParams no hiciste algo como esto?

ViewGroup.LayoutParams params = (AbsListView.LayoutParams) getLayoutParams();

(Eso todavía fallará).

En cualquier caso, usa esto:

ViewGroup.LayoutParams params = getLayoutParams();

Luego, si aún recibes una excepción, publica esa, no la que tiene el casting.


Para entender lo que sucede aquí, debes buscar en la fuente de Android. Hay un método en ViewGroup generateLayoutParams que JavaDoc establece:

Devuelve un conjunto seguro de parámetros de diseño basados ​​en los parámetros de diseño suministrados. Cuando se pasa a un Grupo de Vista una Vista cuyos parámetros de diseño no pasan la prueba de checkLayoutParams(android.view.ViewGroup.LayoutParams) , se invoca este método. Este método debería devolver un nuevo conjunto de parámetros de diseño adecuados para este grupo de vistas, posiblemente copiando los atributos apropiados del conjunto especificado de parámetros de diseño.

Si observa LinearLayout y AbsListView (el padre de GridView), verá que convierten sus parámetros de diseño hijos en LinearsLayout.LayoutParams y AbsListView.LayoutParams respectivamente. Pero esta conversión solo ocurre cuando el niño se agrega al diseño.
Por lo tanto, si agrega su TouchButton a LinearLayout (programáticamente o mediante XML), recibirá LinearsLayout.LayoutParams y, si lo agrega a GridView (a través de un adaptador), recibe AbsListView.LayoutParams .
Pero si configura los parámetros de diseño manualmente después, obtendrá ClassCastException en algún lugar del código contenedor primario (ya que espera que los parámetros de diseño hijos sean de algún tipo específico).

Para la solución de su problema, le sugiero lo siguiente:

private void setLayout(buttonsize_t size) { log("Setting Layout: "+buttonsize_t.getPxl(size)); final float scale = getContext().getResources().getDisplayMetrics().density; int dim = (int) (buttonsize_t.getPxl(size) * scale + 0.5f); ViewGroup.LayoutParams params = (ViewGroup.LayoutParams) getLayoutParams(); if (params != null) { params.height = dim; params.width = dim; setLayoutParams(params); } else { // the LayoutParams was not set yet, it must be the GridView // which delays setting till child rendering params = new AbsListView.LayoutParams(dim, dim); setLayoutParams(params); } }