Contesto Android BaseAdapter
-
22-12-2019 - |
Domanda
Frammenti
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//inflater provided
View view;
...
return view;
}
Adattatore base:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//have to make a constructor to get an inflater
....
return view;
}
Perché lo fa BaseAdapter
'S getView()
i parametri del metodo non forniscono un file LayoutInflater
a differenza di Fragment
'S onCreateView()
?In cui in questo metodo ci si aspetta che gonfiare visualizzazioni?
Per gonfiare le visualizzazioni è necessario avere un riferimento a an LayoutInflater
.
Soluzione
IL "perché un metodo getView non utilizza il contesto come parametro" risiede nel suo utilizzo.Ci sono molte differenze tra Activity
, Fragment
E Adapter
, giusto per ricordare:
- UN Attività è una cosa unica e mirata che l'utente può fare. Quasi tutte le attività interagiscono con l'utente, quindi la classe Activity si occupa di creare una finestra in cui puoi posizionare la tua interfaccia utente.
- UN Frammento È una parte dell'interfaccia utente di un'applicazione o comportamento che può essere inserito in un'attività.
- UN Adattatore L'oggetto funge da ponte tra un AdapterView e i dati sottostanti per quella vista.È altresì responsabile della creazione di una vista per ciascun elemento nel set di dati.
C'è una grande differenza nel suo utilizzo e per essere più specifici:
- Un'attività implementa
onCreate
e chiamatesetContentView(int)
A gonfiare l'interfaccia utente dell'attività. - Il Frammento utilizza
onCreateView
metodo a creare un'istanza della visualizzazione dell'interfaccia utente. - Mentre l'adattatore utilizza
getView
A ottenere una vista che visualizza i dati nella posizione specificata, crea una vista manualmente o gonfiala da un file di layout XML.
La differenza principale è che Activity e Fragment ritornano una vista dell'interfaccia utente mentre ritorna un adattatore la vista che avviene all'interno dell'interfaccia utente. L'utente non interagisce con l'adattatore.
getView()
il metodo non fornisce a LayoutInflater
(o a Context
) come parametro perché questo metodo restituisce una vista corrispondente ai dati nella posizione specificata e non un'interfaccia utente.Quindi, questo metodo necessita di a parent view
invece di a context
perché restituisce molte visualizzazioni (in un ciclo) e non solo un'interfaccia.
Non ne sono sicuro, comunque penso, come Manish Mulimani detto, questo è anche un modo per risparmiare risorse, perché se esegui un ciclo per creare molte visualizzazioni e allegare ogni volta l'intero contesto, utilizzerai alcune risorse inutili solo per visualizzare le visualizzazioni semplici nella tua interfaccia utente.
Altri suggerimenti
Uno dei motivi potrebbe essere che la maggior parte delle volte le visualizzazioni verranno riutilizzate.Quando la vista viene riutilizzata, ad es.il secondo parametro View non è nullo, non utilizzerai il Gonfiatore.Quindi questo potrebbe essere il motivo per cui l'API è stata progettata in questo modo.
In caso di frammenti, dovrai creare un layout utilizzando le API o gonfiando una risorsa.Poiché la procedura consigliata consiste nel separare la progettazione dell'interfaccia utente dal comportamento dell'attività, la maggior parte delle volte viene utilizzato Inflater.Queste sono le dichiarazioni fornite nell'art documentazione ufficiale.
Per restituire un layout da OnCreateView (), è possibile gonfiarlo da una risorsa di layout definita in XML.Per aiutarti a farlo, OnCreateView () fornisce un oggetto LayoutInflater.
Non vedo quale sia il problema...
public class MyAdapter extends BaseAdapter {
private LayoutInflater inflater;
public MyAdapter(Context context) {
inflater = LayoutInflater.from(context);
}
...
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(...);
}
...
}
Nel costruttore ottieni il contesto e i dati che desideri che l'adattatore utilizzi.inoltre, devi occuparti dei metodi getItem() e getCount().
il metodo getView() chiama ogni volta che la vista che utilizza l'adattatore deve disegnare se stessa.dovresti controllare se la vista convertita è null, se è null dovresti gonfiare il tuo layout lì e altrimenti devi creare la rootview dalla vista convertita.(La vista convertita è il meccanisem che aiuta l'adattatore ad essere più eficiente, gli oggetti di visualizzazione dei ricicli dell'adattatore invece di creare nuovi oggetti visualizzati, se non aggiungi questo controllo che la tua galleria non funzionerà senza intoppi)
Ecco un esempio di un adattatore di base che visualizza i nomi dei campionati che ha recitato come un array:
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.LinearLayout;
import android.widget.TextView;
public class GalleryAdapter extends BaseAdapter {
Context context;
private String[] leaguesName;
public GalleryAdapter(Context context,String[] leaguesName )
{
this.context=context;
this.leaguesName=leaguesName;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return leaguesName.length;
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return leaguesName[arg0];
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View root;
counter++;
if(convertView==null)
{
LayoutInflater lif = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
root=lif.inflate(R.layout.gallery_text_view, null);
}
else
root=convertView;
TextView tv =(TextView) root.findViewById(R.id.league_name_tv);
tv.setText(leaguesName[position]);
return root;
}
}
Non hai necessariamente bisogno di LayoutInflater, puoi fare:
View.inflate(contesto, risorsa, genitore)
Per quanto riguarda il Context
sottoclassi di BaseAdapter
fornisci getContext()
.Non so perché BaseAdapter non abbia un parametro Context nel costruttore, probabilmente da creare BaseAdapter
il più astratto possibile.
Infatti, BaseAdapter
utilizza solo l'astrazione View
E ViewGroup
E DataSetObserver
astrazioni. Context
sarebbe un dettaglio di implementazione e così BaseAdapter
non lo usa.