Android – Escribir un componente personalizado (compuesto)

La aplicación para Android que estoy desarrollando actualmente tiene una actividad principal que ha crecido bastante grande. Esto se debe principalmente a que contiene un TabWidget con 3 pestañas. Cada pestaña tiene bastantes componentes. La actividad tiene que controlar todos esos componentes a la vez. Así que creo que usted puede imaginar que esta actividad tiene como 20 campos (un campo para casi todos los componentes). También contiene mucha lógica (click listeners, lógica para llenar listas, etc).

Lo que normalmente hago en los marcos basados ​​en componentes es dividir todo en componentes personalizados. Cada componente personalizado tendría entonces una clara responsabilidad. Contendría su propio conjunto de componentes y toda otra lógica relacionada con ese componente.

Traté de averiguar cómo se puede hacer esto, y encontré algo en la documentación de Android que les gusta llamar un "Control compuesto". (Vea http://developer.android.com/guide/topics/ui/custom-components.html#compound y desplácese hasta la sección "Controles compuestos") Me gustaría crear un componente basado en un archivo XML que defina el Vista estructura.

En la documentación dice:

Tenga en cuenta que al igual que con una actividad, puede utilizar el enfoque declarativo (basado en XML) para crear los componentes contenidos o puede anidarlos mediante programación de su código.

Bueno, eso es una buena noticia! ¡El enfoque basado en XML es exactamente lo que quiero! Pero no dice cómo hacerlo, excepto que es "como con una actividad" … Pero lo que hago en una actividad es llamar a setContentView(...) para inflar las vistas desde XML. Ese método no está disponible si por ejemplo subclase LinearLayout .

Así que traté de inflar el XML manualmente como este:

 public class MyCompoundComponent extends LinearLayout { public MyCompoundComponent(Context context, AttributeSet attributeSet) { super(context, attributeSet); LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); inflater.inflate(R.layout.my_layout, this); } } 

Esto funciona, excepto por el hecho de que el XML que estoy cargando ha declarado LinearLayout como el elemento raíz. Esto resulta en el inflado LinearLayout siendo un hijo de MyCompoundComponent que ya es un LinearLayout !! Así que ahora tenemos un LinearLayout redundante entre MyCompoundComponent y las vistas que realmente necesita.

¿Puede alguien por favor proporcionarme una mejor manera de abordar esto, evitando tener un LinearLayout redundante instanciado?

2 Solutions collect form web for “Android – Escribir un componente personalizado (compuesto)”

Utilice la etiqueta de mezcla como su raíz XML

 <merge xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Your Layout --> </merge> 

Compruebe este artículo.

Creo que la forma en que se supone que debes hacerlo, es usar el nombre de tu clase como elemento raíz XML:

 <com.example.views.MyView xmlns:.... android:orientation="vertical" etc.> <TextView android:id="@+id/text" ... /> </com.example.views.MyView> 

Y luego haga que su clase se derive de cualquier disposición que desee usar. Tenga en cuenta que si está utilizando este método no utiliza el inflador de diseño aquí.

 public class MyView extends LinearLayout { public ConversationListItem(Context context, AttributeSet attrs) { super(context, attrs); } public ConversationListItem(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void setData(String text) { mTextView.setText(text); } private TextView mTextView; @Override protected void onFinishInflate() { super.onFinishInflate(); mTextView = (TextView)findViewById(R.id.text); } } 

Y, a continuación, puede utilizar su vista en los diseños XML como de costumbre. Si desea hacer la vista programáticamente, tiene que inflarlo usted mismo:

 MyView v = (MyView)inflater.inflate(R.layout.my_view, parent, false); 

Desafortunadamente esto no le permite hacer v = new MyView(context) porque no parece haber una forma de evitar el problema de layouts anidados, así que esto no es realmente una solución completa. Podrías agregar un método como éste a MyView para hacerlo un poco mejor:

 public static MyView create(Context context) { return (MyView)LayoutInflater.fromContext(context).inflate(R.layout.my_view, null, false); } 

Disclaimer: Puedo estar hablando de bollocks completos.

  • Pojo analiza gson con nombres de java no válidos
  • Cambiar el fondo ListView - comportamiento extraño
  • Android - ImageLoader debe ser init con la configuración antes de usar en UIL
  • Java.security.cert.CertPathValidatorException: Ancla de confianza para ruta de certificación no encontrada. Android 2.3
  • No se pudo importar el nuevo proyecto de Gradle: no se pudo encontrar la revisión de las herramientas de compilación * .0.0
  • Arraylist de clasificación de Android por propiedades
  • Crear varias tablas para una clase en ORMLite
  • SSLSocket a través de otro SSLSocket
  • El cajón de navegación no funciona cuando startActivity se utiliza en el primer caso de selectItem
  • Cargar imagen de compresión en un servidor mediante retroadaptación
  • Android java.lang.IllegalStateException: No se pudo ejecutar el método de la actividad
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.