2010-09-13 14 views
27

Jak przekazać bieżący atrybut AttributeSet do niestandardowej klasy widoku? Jeśli użyję konstruktora, który ma tylko kontekst w argumentach, tracę wszystkie motywy i możliwość używania znaczników "stylu" w xml dla tego niestandardowego widoku.Jak przekazać atrybut AttributeSet do niestandardowego widoku

Utworzyłem działanie, które zawiera mój niestandardowy widok już w pliku xml, a następnie programowo utworzę nowy i dodaję go do układu. To co znajduję to to, co jest zrobione w xml ma odpowiednią stylizację, a ta, którą tworzę programowo, nie.

Różnica między tymi dwoma, o ile wiem, polega na tym, że system używa konstruktora CustomLayout1(Context context, AttributeSet attrs). Problem polega na tym, że nie mogę wymyślić, w jaki sposób uzyskać atrybut AttributeSet, aby aplikacja mogła przejść do tego niestandardowego widoku podczas jego tworzenia programowego.

Oto aktywny:

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

Oto główny xml:

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

Klasa niestandardowy widok:

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

wreszcie zwyczaj widok 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> 

Odpowiedz

27

Zamiast budować go za pomocą layout.addView (new CustomLayout1 (getApplicationContext())); nadmuchać go z LayoutInflater w swojej działalności.

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

Simple. Elegancki. Dziękuję Ci. Powinienem był o tym pomyśleć :-P To strasznie denerwujące zachowanie, które chciałbym zobaczyć. Zaimplementowałem to rozwiązanie w moim głównym kodzie i oczywiście odkryłem mnóstwo innych powiązanych kwestii. Wygląda na to, że motyw i styl po prostu znikną tak tajemniczo ze względu na sposób w jaki wywołujesz niestandardowy widok. * westchnienie * – atraudes

+0

[Poniżej znajduje się pełniejszy przykład zastosowania kreatora układu do skopiowania niestandardowego widoku.] (http://stackoverflow.com/a/41500409/3681880) – Suragch

2

Co próbujesz osiągnąć tutaj? Wygląda na to, że masz tutaj nieskończoną pętlę rekurencyjną, używając metody create, ponieważ metoda inflate() wywoła konstruktor, który przyjmuje atrybuty. W każdym razie, aby odpowiedzieć na twoje pytanie, otrzymasz atrybuty w konstruktorze z atrybutami!

To jest konstruktor, który jest wywoływany podczas ładowania z XML, w przeciwnym razie wywołuje jeden z innych konstruktorów, które dostarczasz.

Jedna z innych pomocnych rzeczy, można uzyskać odniesienie do inflatora o wiele łatwiej ze statycznej metody View. View.inflate: D

+0

To była klasa Test zrobiłem rozwiązać problem mam w innym projekcie. Tworzę niestandardowe widoki i dodaje je do widoku galerii. Problem, który mam, polega na tym, że nie mogę zastosować tematu, którego używam do niczego wewnątrz niestandardowej klasy. To wydaje się zboczone i błędne :-P Moje pytanie brzmi: jak uzyskać zestawy atrybutów w działaniu, aby przejść do mojej klasy niestandardowej? Jestem obecnie to robi: nowy CustomLayout1 (getApplicationContext()) i chciałbym zrobić coś takiego zamiast: nowego CustomLayout1 (getApplicationContext(), AttributeSet) w nadziei, że to faktycznie zastosować mój motyw – atraudes

+0

I dziękuję za wskazówkę dotyczącą view.inflate.Bardzo użyteczne :-D – atraudes

+0

dostaniesz je w konstruktorze, po prostu uczynić członkiem AttributeSet mAttset = attrs – schwiz

3

Twój kod tworzy LinearLayout wewnątrz układu liniowego dla widoku niestandardowego. Poprawny sposób to zrobić jest zmiana widoku niestandardowego xml z:

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

do

<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

Dodawanie odwołania do http://developer.android.com /training/improving-layouts/reusing-layouts.html i http://stackoverflow.com/questions/2732682/simple-example-of-merge-and-include-usage-in-android-xml-layouts – EpicPandaForce

Powiązane problemy