Konvertovanje XML resursa u View objekat (“Layout Inflating”)

Uvod

“Layout inflation” je termin koji označava postupak sa kojim se XML resurs parsira i konvertuje u View objekat.
Aktivnost ima svoju metodu setContentView() sa kojom inflate-uje svoj root view:

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

Ali konvertovanje drugih layout-a u View objekt (čime omogućavamo da elementi layout-a budu dostupni u kodu aktivnosti) možemo da uradimo na sledeće načine:

  1. Koristići inflate() metodu inflater objekta
  2. Koristeći statičnu metodu inflate() View klase

Metoda LayoutInflater.inflate()

Ovaj postupak se sastoji iz dva koraka:

  1. Pravljenje Inflater objekat
  2. Pozivanje inflate() metode

Pravljenje Inflater objekta

U aktivnosti

a) u okviru onCreate()

Ako smo u aktivnosti u sklopu onCreate() metode možemo da pristupimo ovom objektu jednostavno jer je dat kao parametrar metode onCreate():

 View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
b) van onCreate() metode

Medjutim ako smo van onCreate() metode moramo mu pristipiti na drugačiji način koristeći getLayoutInflater() metodu:

 LayoutInflater inflater = getLayoutInflater();

Van aktivnosti

a) Preko aktivnosti

Pa čak ako smo i van aktivnosti možemo mu pristupiti pozivajući aktivnost:

getActivity().getLayoutInflater();
b) Preko context-a

Koristeći metodu context.getSystemService(Class)

LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
Primer
public MyAdapter(Context context, List objects) extends ArrayAdapter {
  super(context, 1, objects);
  /* We get the inflator in the constructor */
  mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

ili na drugi način koristeći from() metod:

LayoutInflater inflater = LayoutInflater.from(context);

Pozivanje inflate() metode

Pozivanjem “inflate()” metode se vrši konverzija:

public View inflate (int resource,ViewGroup root,boolean attachToRoot)
Legenda:
  • resource int: ID resursa
  • root ViewGroup: Opciona vrednost koja predstavlja neki View group koji će da bude roditelj ovom view-u (ako je treći parametar “attachToRoot” setovan na true). Ova vrednost može pri pozivu funkcije da bude null!
  • attachToRoot boolean: Kroz ovaj parametar se definiše šta će biti vraćeno iz metode. Ako je attachToRoot postavljen na true, onda je layout file navedena u prvom parametru inflate-ovana i priključena na ViewGroup definisan u drugom parametru, pa tada metod vraća ovaj kombinovani prikaz, sa ViewGroup kao root. Kada je attachToRoot false, layout file iz prvog parametra se inflate i vraća kao prikaz.
Primer
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
	View rootView = inflater.inflate(R.layout.fragment_main, container, false);
	return rootView;
}

U ovome primeru treći parametar je “false” pa naš view nije ubačen u parent view (ovde container). Ako želimo da view bude ubačen u neki parent view potrebno je da stavimo “true” ili da to naknadno uradimo sa dodatnim kodom koristeć metodu addView().

Primer
Button button = (Button) inflater.inflate(R.layout.custom_button, mLinearLayout, false);
mLinearLayout.addView(button);

NAPOMENA:
Postoji verzija i sa dva parametra (treći parametar je uvek true)

public View inflate (int resource, ViewGroup root)

Statična metoda inflate() View klase

Za istu namenu može da se koristi i STATIČNA metoda View objekta inflate(). Ona u pozadini takodje koristi wrap-ovani inflater objekat čiji kod izgleda ovako:

public static View inflate(Context context, int resource, ViewGroup root) {
    LayoutInflater factory = LayoutInflater.from(context);
    return factory.inflate(resource, root);
}
Primer

Ova statićna metoda se najčešće koristi kod slučaja kada se definiše custom VIew:

public void init (Context context, AttributeSet attrs) {
    customView = inflate(context, R.layout.view_custom, this);
}

Što bi bilo poptuno jednako sledećem kodu uradjenom preko inflator objekta:

 public void init (Context context, AttributeSet attrs) {
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
    View customView = inflater.inflate(R.layout.view_custom, this, true);
}

Jedna od razlika je što u ovoj statičnoj metodi nemamo opciju sa tri parametra (to znači da je treći parametar uvek true)