2010-11-19 11 views
11

ho creato una preferenza personalizzato che ha il seguente costruttoreonCreateView() chiamato troppo spesso a preferenza personalizzato

public CoordinatesPreference(Context context, AttributeSet attrs) 
{ 
    super(context, attrs); 
    setLayoutResource(R.layout.coordinates_preference); 
} 

E ho sovrascritto onCreateView() così scrive nel registro come questo:

@Override 
protected View onCreateView(ViewGroup parent) 
{ 
    Log.d("test", "Creating Preference view"); 
    return super.onCreateView(parent); 
} 

e il mio registro è pieno di "Creating Preference view" messaggi, questo crea una sensazione di rallentamento per lo scorrimento e credo che la vista di conversione dovrebbe risolvere questo, ho dato un'occhiata al codice sorgente delle preferenze e se la vista di conversione è nullo viene chiamato onCreateView().

a scopo di test ho aggiunto questo metodo:

@Override 
public View getView(View convertView, ViewGroup parent) 
{ 
    if (convertView == null) 
    { 
     return super.getView(convertView, parent); 
    } 
    return super.getView(convertView, parent); 
} 

e impostare un punto di interruzione. Ho scoperto che quasi sempre la mia vista di conversione è nullo. e quindi deve creare una nuova visione, perché è questo? e come posso migliorare questo per evitare una schermata di preferenza laggiante?

MODIFICA: Modificato il modo in cui viene chiamato onCreate, ora è tutto Android. Io uso solo setLayoutResource. ma questo non risolve il problema ...

EDIT2: ho usato Debug.StartMethodTracing() e ho trovato come sospetto che il 55% del tempo trascorso (quando sto solo scorrendo su e giù) sia speso per l'inflazione di la preferenza dal metodo onCreateView() che viene chiamato da getView() quando convertView è nullo.

Grazie, Jason

+0

Puoi incollare uno screenshot di come appaiono le tue preferenze? – Macarse

+0

Sicuro. Ne posterò uno quando arrivo a casa – Jason

+0

Puoi mettere il tuo file preferences.xml? Ho un'idea su questo e vorrei confermare che la tua configurazione è come la mia. – ThomasW

risposta

0

Ero in esecuzione in questo problema e ho rintracciato il fatto che ho avuto il layout impostato sia nel file preferences.xml e nel mio metodo di sottoclasse PreferenceCreateView(). Quando ho rimosso il layout da preferences.xml, onCreateView() ha smesso di essere chiamato più volte.

3

Non so cosa hai implementato in questa preferenza su misura, ma forse la super classe non sa come creare una vista adeguata alle proprie preferenze?

Dalla documentazione:

protetta View onCreateView (ViewGroup genitore)

dal: API livello 1 crea la vista per essere mostrato per questa preferenza nel PreferenceActivity. Il comportamento predefinito è per gonfiare il layout principale di questa preferenza (vedi setLayoutResource (int). Se la modifica questo comportamento, si prega di specificare un ViewGroup con ID widget_frame. Assicurarsi assicurarsi di chiamare fino alla realizzazione dei della superclasse.

http://developer.android.com/reference/android/preference/Preference.html

immagino di aver impostato che id sul layout orizzontale.

Ora che sto parlando di esso, wh y non includi questo layout orizzontale nel layout che stai gonfiando?

+0

Grazie, ma ho già il layout nel layout orizzontale in xml, e Android non sa come gonfiare la mia preferenza (dato che sto ottenendo un risultato operativo) tuttavia è laggy da scorrere perché oCreate() è chiamato così spesso (questo è ciò che la vista convertita dovrebbe risolvere) – Jason

0

come una risposta più generale, non specificamente relative alle preferenze personalizzate:

E 'difficile vedere con il codice che avete inviato, ma se le vostre esigenze per tirare una preferenza ogni volta che si crea una vista, sarà molto lento e lento come descrivi.Anche se la vista esiste, devi comunque impostare il valore e sembra che debba venire dalla preferenza. Le letture delle preferenze Android sono incredibilmente lente, quindi non possono essere associate alla creazione dell'interfaccia utente se si desidera una buona esperienza veloce.

Penso che dovresti memorizzare le preferenze nell'app (magari nell'Attività, o sottoclassi l'Applicazione e memorizzarle lì), al fine di implementare alcuni semplici caching. La prima volta che hai bisogno di una preferenza, la richieda dal negozio della tua app, se non è presente, estraila dalle preferenze. Se la preferenza è già memorizzata nell'attività/nell'applicazione, utilizzare tale valore senza raggiungere le pref. Quindi, quando scrivi i prefs, scrivi al negozio E la preferenza. In questo modo non importa quanto spesso getView() debba creare nuove viste, poiché è possibile accedere rapidamente alle preferenze utilizzando la copia nell'oggetto attività/applicazione, ma anche memorizzate in modo duraturo nelle preferenze per il futuro.

Non so se il framework delle preferenze ha qualche cache in esso da qualche parte, ma la mia esperienza di caricamento dei prefs è che se alcuni hanno bisogno di caricare l'utente noterà un ritardo, quindi il caching è essenziale.

+0

La preferenza è memorizzata nella cache locale, nessuna lettura e scrittura ridondanti da o verso le preferenze condivise. – Jason

1

Non sono sicuro che il codice che si sta utilizzando sia un test accurato. Ho una preferenza personalizzata e sovrascrivo solo 5 metodi e tre di loro sono costruttori.

public ImageButtonPreference(Context context) 
{ 
    this(context, null); 
} 

public ImageButtonPreference(Context context, AttributeSet attrs) 
{ 
    this(context, attrs, 0); 
} 

public ImageButtonPreference(Context context, AttributeSet attrs, int defStyle) 
{ 
    super(context, attrs, defStyle); 
    mInflater = LayoutInflater.from(context); 

    // This is where I pull all of the styleable info from the attrs 
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ImageButtonPreference, defStyle, 0); 
    for(int i = a.getIndexCount(); i >= 0; i--) 
    { 
     int attr = a.getIndex(i); 
     switch (attr) 
     { 
     case R.styleable.ImageButtonPreference_logo: 
      mImageResource = a.getResourceId(attr, mImageResource); 
      break; 
     case R.styleable.ImageButtonPreference_button_text: 
      mButtonText = a.getString(attr); 
      break; 
     } 
    } 
} 

@Override 
protected View onCreateView(ViewGroup parent) 
{ 
    View view = mInflater.inflate(R.layout.image_button_preference, parent, false); 
    return view; 
} 

@Override 
protected void onBindView(View view) 
{ 
    super.onBindView(view); 

    ImageView image = (ImageView)view.findViewById(R.id.Logo); 
    if(image != null && mImageResource != 0) image.setImageResource(mImageResource); 

    Button button = (Button)view.findViewById(R.id.ConnectButton); 
    if(button != null) 
    { 
     button.setText(mButtonText); 
     button.setOnClickListener(mButtonListener); 
    } 
} 

Ho tirato questo codice, quasi alla lettera dalla Sorgente di Android, quindi dovrebbe essere altrettanto veloce di qualsiasi altra preferenza.

+0

Sì, il mio codice è molto simile a quello. – Jason

Problemi correlati