2010-09-13 18 views
27

¿Cómo paso el AttributeSet actual a una clase de vista personalizada? Si utilizo un constructor que solo tiene Contexto en los argumentos, pierdo todos los temas y la capacidad de usar etiquetas de "estilo" en el xml para esa Vista personalizada.Cómo pasar AttributeSet a la vista personalizada

Lo que he hecho es crear una actividad que contenga mi vista personalizada ya en el archivo xml, y luego crear programáticamente una nueva y agregarla al diseño. Lo que encuentro es que el que está hecho en el xml tiene el estilo adecuado, y el que creo mediante programación no.

La diferencia entre los dos hasta donde puedo decir es que el sistema usa el constructor CustomLayout1(Context context, AttributeSet attrs). El problema es que no puedo entender cómo obtener el AttributeSet para que la aplicación pase a esta vista personalizada cuando lo creo mediante programación.

Aquí está la Actividad:

import android.app.Activity; 
import android.os.Bundle; 
import android.widget.LinearLayout; 

public class ThemeOne extends Activity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     LinearLayout layout = (LinearLayout) findViewById(R.id.mainlayout); 

     layout.addView(new CustomLayout1(getApplicationContext())); 
    } 
} 

Aquí está el código XML principal:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical" 
android:id="@+id/mainlayout" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent"> 
<com.clearsync.test.theme1.CustomLayout1 android:id="@+id/maincustom" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" /> 
</LinearLayout> 

La clase vista personalizada:

import com.clearsync.test.theme1.R; 

import android.content.Context; 
import android.util.AttributeSet; 
import android.view.LayoutInflater; 
import android.widget.LinearLayout; 

public class CustomLayout1 extends LinearLayout { 
private Context context = null; 

public CustomLayout1(Context context) { 
    super(context); 
    this.context = context; 
    create(); 
} 

public CustomLayout1(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    this.context = context; 
    create(); 
} 

private void create(){ 
    LayoutInflater layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    layoutInflater.inflate(R.layout.inflateme, this, true); 
} 
} 

y, finalmente, la vista personalizada xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent"> 
<TextView android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Oh, Hewroh..." 
    style="?textview_style1" /> 
</LinearLayout> 

Respuesta

27

En lugar de compilarlo con layout.addView (new CustomLayout1 (getApplicationContext())); inflarlo con LayoutInflater en tu actividad.

LayoutInflater inflater = LayoutInflater.from(this); 
inflater.inflate(R.layout.yourcustomviewxml, layout); 
+1

Simple. Elegante. Gracias. Debería haberlo pensado yo mismo :-P Ese es un comportamiento terriblemente molesto que me gustaría ver arreglado. Implementé esa solución en mi código principal y, por supuesto, descubrí un montón de otros problemas relacionados. Parece un error que el tema y el estilo simplemente desaparecerían tan misteriosamente simplemente por la forma en que llamas una vista personalizada. * suspiro * – atraudes

+0

[Este es un ejemplo más completo del uso de un Inflater de diseño para copiar una vista personalizada.] (http://stackoverflow.com/a/41500409/3681880) – Suragch

2

¿Qué estás tratando de lograr aquí? Parece que tienes aquí un bucle recursivo sin fin usando tu método de creación, ya que inflate() llamará al constructor que toma los atributos. De todos modos para responder a su pregunta, ¡obtiene los atributos en el constructor con los atributos!

Ese es el constructor que se llama al cargar desde XML, de lo contrario llama a uno de los otros constructores que usted proporciona.

Otra cosa útil, puede obtener una referencia al inflador mucho más fácil desde el método de vista estático. View.inflate: D

+0

Esta era una clase de prueba que hice para resolver un problema que estoy teniendo en otro proyecto. Estoy creando vistas personalizadas y las estoy agregando a una vista de galería. El problema que tengo es que no puedo aplicar el tema que estoy usando a nada dentro de una clase personalizada. Esto parece pervertido e incorrecto :-P Mi pregunta es ¿cómo obtengo los conjuntos de atributos en la actividad para pasar a mi clase personalizada? Actualmente estoy haciendo esto: nueva CustomLayout1 (getApplicationContext()) y me gustaría hacer algo como esto en su lugar: nueva CustomLayout1 (getApplicationContext(), AttributeSet) con la esperanza de que sería en realidad aplicar mi tema – atraudes

+0

Y gracias por tu consejo en view.inflate.Muy útil :-D – atraudes

+0

los obtienes en el constructor, simplemente crea un miembro AttributeSet mAttset = attrs – schwiz

3

Su código crea LinearLayout dentro del diseño lineal para su vista personalizada. forma correcta de hacer esto está cambiando la vista personalizada XML desde:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent"> 
<TextView android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Oh, Hewroh..." 
    style="?textview_style1" /> 
</LinearLayout> 

a

<merge xmlns:android="http://schemas.android.com/apk/res/android"> 
<TextView android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Oh, Hewroh..." 
     style="?textview_style1" 
/> 
</merge> 
+0

Agregando referencia a http://developer.android.com /training/improving-layouts/reusing-layouts.html y http://stackoverflow.com/questions/2732682/simple-example-of-merge-and-include-usage-in-android-xml-layouts – EpicPandaForce

Cuestiones relacionadas