2010-09-13 16 views
27

Come si passa all'attuale AttributeSet a una classe di visualizzazione personalizzata? Se utilizzo un costruttore che ha solo Context negli argomenti, perdo tutti i temi e la possibilità di utilizzare i tag "style" nell'xml per quella visualizzazione personalizzata.Come passare AttributeSet alla vista personalizzata

Quello che ho fatto è creare un'attività che contenga la mia vista personalizzata già nel file xml, quindi crearne una nuova a livello di codice e aggiungerla al layout. Quello che trovo è quello che è fatto nel xml ha lo stile corretto, e quello che creo programmaticamente non lo fa.

La differenza tra i due per quanto posso dire è che il sistema utilizza il costruttore CustomLayout1(Context context, AttributeSet attrs). Il problema è che non riesco a capire come ottenere AttributeSet affinché l'applicazione passi a questa visualizzazione personalizzata quando la creo a livello di programmazione.

Ecco l'Activity:

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())); 
    } 
} 

Ecco il xml principale:

<?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 classe visualizzazione personalizzata:

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); 
} 
} 

e, infine, la visualizzazione personalizzata 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> 

risposta

27

Invece di costruirlo con layout.addView (nuovo CustomLayout1 (getApplicationContext())); gonfialo con il LayoutInflater nella tua attività.

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

Semplice. Elegante. Grazie. Avrei dovuto pensarci anch'io :-P Questo è un comportamento terribilmente fastidioso che mi piacerebbe vedere risolto. Ho implementato questa soluzione nel mio codice principale e, naturalmente, ho scoperto una serie di altri problemi correlati. Sembra un bug che il tema e lo stile sarebbero semplicemente scomparsi così misteriosamente semplicemente per il modo in cui si chiama una vista personalizzata. * sigh * – atraudes

+0

[Ecco un esempio più completo di utilizzo di un Inflater layout per copiare una visualizzazione personalizzata.] (http://stackoverflow.com/a/41500409/3681880) – Suragch

2

Cosa stai cercando di realizzare qui? Sembra che tu abbia un ciclo ricorsivo infinito qui usando il tuo metodo di creazione, dato che inflate() chiamerà il costruttore che prende gli attributi. Ad ogni modo per rispondere alla tua domanda ottieni gli attributi nel costruttore con gli attributi!

Questo è il costruttore chiamato durante il caricamento da XML, altrimenti chiama uno degli altri costruttori forniti dall'utente.

Un'altra cosa utile, è possibile ottenere un riferimento al gonfiatore molto più semplice dal metodo di visualizzazione statico. View.inflate: D

+0

Questa era una classe di test che ho fatto per risolvere un problema che sto avendo in un altro progetto. Sto creando visualizzazioni personalizzate e aggiungendole in una vista galleria. Il problema che sto avendo è che non posso applicare il tema che sto usando a qualcosa all'interno di una classe personalizzata. Questo sembra pervertito e sbagliato :-P La mia domanda è come faccio a ottenere i set di attributi nell'attività per passare alla mia classe personalizzata? Attualmente sto facendo questo: nuova CustomLayout1 (getApplicationContext()) e mi piacerebbe fare qualcosa di simile, invece: nuova CustomLayout1 (getApplicationContext(), AttributeSet) nella speranza che sarebbe effettivamente applicare la mia tema – atraudes

+0

E grazie per il suggerimento su view.inflate.Molto utile :- – atraudes

+0

si ottiene nel costruttore, basta creare un membro AttributeSet mAttset = attrs – schwiz

3

Il codice crea LinearLayout all'interno del layout lineare per la visualizzazione personalizzata. modo corretto di fare questo sta cambiando la visualizzazione XML personalizzato da:

<?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

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

Problemi correlati