Cambia font listView contenuta in un arrayAdapter

di il
22 risposte

Cambia font listView contenuta in un arrayAdapter

Salve amici ho un problema . Ho un arrayAdapter costituito da un'immagine statica e del testo dinamico. Vorrei cambiare il font del testo contenuto nella listView che a sua volta è adattato tramite arrayAdapter. Avete gentilmente qualche consiglio da darmi? Grazie in anticipo per la risposta.
Io ho fatto una cosa del genere ma non funziona
protected void onPostExecute(String result)
        {
            // dopo che ho eseguito il parsing mostro i dati nella listview
            // usando l' array adpater
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(Seconda.this, R.layout.layout_riga, R.id.testo, titoli);

            // Codice per cambiare il font
            Typeface myTypeface = Typeface.createFromAsset(getAssets(),"Quattrocento.ttf");
            TextView waitingTimeView = (TextView) findViewById(R.id.testo);
            waitingTimeView.setTypeface(myTypeface);



            date1.setAdapter(adapter);
            mProgressDialog.dismiss();



        }

22 Risposte

  • Re: Cambia font listView contenuta in un arrayAdapter

    Ciao, per cambiare il font di una lista devi agire da dentro l'adapter, in particolare dentro al metodo getView. E' da questo, infatti, che puoi accedere al layout della cella (cioè R.layout.layout_riga)
  • Re: Cambia font listView contenuta in un arrayAdapter

    Ciao Della, dovrei fare un adapter customizzato praticamente? Ho provato a dare un'occhiata in rete e ho creato una classe "CustomAdapter" che estende "BaseAdapter" ed ho automaticamente implementato i metodi obbligatori di BaseAdapter, in questo modo:
    public class CustomAdapter extends BaseAdapter {
    
        public CustomAdapter(??)
        {
           ??
        }
    
        @Override
        public int getCount() {
            return 0;
        }
    
        @Override
        public Object getItem(int position) {
            return null;
        }
    
        @Override
        public long getItemId(int position) {
            return 0;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            return null;
        }
    }
    
    Il mio primo dubbio è il costruttore, cioè questo costruttore che parametri dovrà avere ?
  • Re: Cambia font listView contenuta in un arrayAdapter

    Ciao, secondo me invece di estendere la classe BaseAdapter ti conviene estendere ArrayAdapter<T>, perché quest'ultima fornisce un'implementazione più completa dell'adapter. In pratica generalmente è sufficiente fare l'override del solo metodo ""
  • Re: Cambia font listView contenuta in un arrayAdapter

    Cioè fare una cosa del genere
    public class CustomAdapter extends ArrayAdapter {
        public CustomAdapter(Context context, int resource, int textViewResourceId, List objects) {
            super(context, resource, textViewResourceId, objects);
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            return null;
    }
    
    e in getView andare a specializzare la textView con il font che ho scelto io?
    Scusami ma non ho proprio idea di come si fa -.-
  • Re: Cambia font listView contenuta in un arrayAdapter

    In pratica nel metodo getView devi restituire una view che corrisponde alla i-esima riga della lista. Di conseguenza in questo metodo devi preoccuparti di:
    • ottenere i riferimenti alle singole sub-view che compongono la riga (es: in una riga hai 2 EditText e 1 ImageView, allora ottieni i riferimenti a queste view per poterle poi riempire con i relativi dati)
    • impostare il font desiderato nelle sub-view
    • riempire le sub-view con i dati di interesse
    • restituire la view corrispondente alla riga
  • Re: Cambia font listView contenuta in un arrayAdapter

    Ho seguito i tuoi precisi suggerimenti ed ho scritto questo:
    public class CustomAdapter extends ArrayAdapter {
    
        TextView testo;
    
        public CustomAdapter(Context context, int resource, int textViewResourceId, List objects) {
            super(context, resource, textViewResourceId, objects);
        }
    
       
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
    
            View v = convertView;
    
            // ottenere i riferimenti alle singole sub-view che compongono la riga
            testo = (TextView) v.findViewById(R.id.testoRiga);
    
            // impostare il font desiderato nelle sub-view
            final Typeface tvFont = Typeface.createFromAsset(assets, "Quattrocento.ttf");
            testo.setTypeface(tvFont);
    
            // riempire le sub-view con i dati di interesse
    
            // restituire la view corrispondente alla riga
            return v;
    
    
        }
    
    Il layout della mia riga contiene un'immagine statica e una stringa dinamica quindi per questo ho inserito come riferimento solo il testo.(Corretto ???)
    Poi ho assegnato il font alla stringa, e il riempimento della sub-vien con i dati di interesse non l'ho capito come bisognava fare.
  • Re: Cambia font listView contenuta in un arrayAdapter

    MacGigi ha scritto:


    Il layout della mia riga contiene un'immagine statica e una stringa dinamica quindi per questo ho inserito come riferimento solo il testo.(Corretto ???)
    Sì, l'immagine suppongo che sia stata impostata tramite il layout xml, mentre il testo non può che essere settato dinamicamente.

    Per quanto riguarda la creazione del Typeface, visto che si tratta di un oggetto condiviso fra tutte le righe potresti ottimizzare il codice e creare una variabile d'istanza invece che locale al metodo:
    
    public class CustomAdapter extends ArrayAdapter {
        private Typeface font;
    
        public CustomAdapter(Context context, int resource, int textViewResourceId, List objects) {
            super(context, resource, textViewResourceId, objects);
            font = Typeface.createFromAsset(...);
        }
    }
    
    Per quanto riguarda il riempimento delle sub-view intendo inserire il testo nelle relative TextViews. Esempio:
    
    testo.setText("Random Text");
    
  • Re: Cambia font listView contenuta in un arrayAdapter

    In pratica dovevo solo dargli il metodo per poter dettare la textView, capito.
    Quindi in definitiva la mia classe CustomAdapter è la seguente:
    public class CustomAdapter extends ArrayAdapter {
    
        TextView testo;
        private Typeface font;
    
        Context context;
        AssetManager assets = context.getAssets();
    
    
        public CustomAdapter(Context context, int resource, int textViewResourceId, List objects) {
            super(context, resource, textViewResourceId, objects);
        }
    
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
    
            View v = convertView;
    
            // ottenere i riferimenti alle singole sub-view che compongono la riga
            testo = (TextView) v.findViewById(R.id.testoRiga);
    
            // impostare il font desiderato nelle sub-view
    
            font = Typeface.createFromAsset(assets, "Quattrocento.ttf");
            testo.setTypeface(font);
    
            // riempire le sub-view con i dati di interesse
            testo.setText("Random text");
            // restituire la view corrispondente alla riga
            return v;
    
    
        }
    }
    
    Poi sono andato nell'altra activity dove utilizzavo l'arrayAdapter(si trova nell'asyncTask) e ho scritto questo:
     protected void onPostExecute(String result)
            {
                // dopo che ho eseguito il parsing mostro i dati nella listview
                // usando l' array adpater
               // ArrayAdapter<String> adapter = new ArrayAdapter<String>(Seconda.this, R.layout.layout_riga, R.id.testoRiga, titoli);
    
               // date1.setAdapter(adapter);
              //  mProgressDialog.dismiss();
    
                CustomAdapter adapter1 = new CustomAdapter(Seconda.this, R.layout.layout_riga, R.id.testoRiga, titoli);
                date1.setAdapter(adapter1);
                mProgressDialog.dismiss();
    
            }
        }
    In fase di compilazione non mi da nessun errore, però quando avvio l'app e mi porto sull'attività incriminata l'app si arresta. uffi
  • Re: Cambia font listView contenuta in un arrayAdapter

    In casi come questo guarda sempre cosa dice il LogCat, altrimenti non ne esci fuori!
  • Re: Cambia font listView contenuta in un arrayAdapter

    FATAL EXCEPTION: main
        Process: com.myProgramming.beneventoturnifarmacie, PID: 24415
        java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.AssetManager android.content.Context.getAssets()' on a null object reference
                at com.myProgramming.beneventoturnifarmacie.CustomAdapter.<init>(CustomAdapter.java:24)
                at com.myProgramming.beneventoturnifarmacie.Seconda$Titolo.onPostExecute(Seconda.java:283)
                at com.myProgramming.beneventoturnifarmacie.Seconda$Titolo.onPostExecute(Seconda.java:209)
                at android.os.AsyncTask.finish(AsyncTask.java:632)
                at android.os.AsyncTask.access$600(AsyncTask.java:177)
                at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
                at android.os.Handler.dispatchMessage(Handler.java:102)
                at android.os.Looper.loop(Looper.java:145)
                at android.app.ActivityThread.main(ActivityThread.java:5942)
                at java.lang.reflect.Method.invoke(Native Method)
                at java.lang.reflect.Method.invoke(Method.java:372)
                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)
    Da quanto ne capisco, sembra esserci un errore relativo all'assets ovvero il primo parametro di questa riga di codice
     Typeface myTypeface = Typeface.createFromAsset(getAssets(),"Quattrocento.ttf");
    Infatti quando l'ho compilato la priva volta mi dava errore in quanto non riusciva a prelevare il metodo getAssets() e per questo poi ho aggiunto la classe Context e AssertManager però a quanto pare ho fatto un casino. vero ?
  • Re: Cambia font listView contenuta in un arrayAdapter

    Ora che guardo meglio il tuo codice noto un errore. Tu scrivi:
    
    public class CustomAdapter extends ArrayAdapter {
    
        TextView testo;
        private Typeface font;
    
        Context context;
        AssetManager assets = context.getAssets();
    
    
        public CustomAdapter(Context context, int resource, int textViewResourceId, List objects) {
            super(context, resource, textViewResourceId, objects);
        }
    
    In questo modo la variabile context viene inizializzata a null, per cui nella riga successiva facendo context.getAssets() ti viene sollevata l'eccezione.
    Se guardi bene nel codice che avevo messo qualche post fa, il Typeface veniva creato nel costruttore, dove hai a disposizione un Context valido.
  • Re: Cambia font listView contenuta in un arrayAdapter

    In effetti il context è dichiarato nel costruttore
    Quindi ho modificato quella riga di codice relativa in questo modo:
    font = Typeface.createFromAsset(getContext().getAssets(), "Quattrocento.ttf");
    richiamando il metodo getContext() , e getAssets(). Però lanciando l'app crasha nuovamente. Però questa volta leggendo il logcat, da quanto ne capisco il problema di prima sembra risolto vero?
    E si presenta un nuovo problema per quanto riguarda la view; da quanto ho capito non trova il riferimento di questo elemento
     // ottenere i riferimenti alle singole sub-view che compongono la riga
            testo = (TextView) v.findViewById(R.id.testoRiga);
    
    Possibile ??

    Questo è il logcat ..
    08-28 18:02:01.868    2666-2666/com.myProgramming.beneventoturnifarmacie E/AndroidRuntime? FATAL EXCEPTION: main
        Process: com.myProgramming.beneventoturnifarmacie, PID: 2666
        java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
                at com.myProgramming.beneventoturnifarmacie.CustomAdapter.getView(CustomAdapter.java:35)
                at android.widget.AbsListView.obtainView(AbsListView.java:2347)
                at android.widget.ListView.measureHeightOfChildren(ListView.java:1270)
                at android.widget.ListView.onMeasure(ListView.java:1182)
                at android.view.View.measure(View.java:17547)
                at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
                at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
                at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
                at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
                at android.view.View.measure(View.java:17547)
                at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
                at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
                at android.view.View.measure(View.java:17547)
                at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
                at com.android.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:447)
                at android.view.View.measure(View.java:17547)
                at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
                at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
                at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2615)
                at android.view.View.measure(View.java:17547)
                at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2015)
                at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1173)
                at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1379)
                at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1061)
                at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5885)
                at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
                at android.view.Choreographer.doCallbacks(Choreographer.java:580)
                at android.view.Choreographer.doFrame(Choreographer.java:550)
                at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
                at android.os.Handler.handleCallback(Handler.java:739)
                at android.os.Handler.dispatchMessage(Handler.java:95)
                at android.os.Looper.loop(Looper.java:135)
                at android.app.ActivityThread.main(ActivityThread.java:5257)
                at java.lang.reflect.Method.invoke(Native Method)
                at java.lang.reflect.Method.invoke(Method.java:372)
                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
  • Re: Cambia font listView contenuta in un arrayAdapter

    Citando dalla documentazione:
    convertView: The old view to reuse, if possible. Note: You should check that this view is non-null and of an appropriate type before using. If it is not possible to convert this view to display the correct data, this method can create a new view. Heterogeneous lists can specify their number of view types, so that this View is always of the right type (see getViewTypeCount() and getItemViewType(int)).
    Quindi come vedi la convertView può essere null; in questi casi devi usare un LayoutInflater per creare una view a partire dal file xml. Ad esempio:
    
    public View getView(int position, View convertView, ViewGroup parent) { 
        if (convertView == null) {
            LayoutInflater inflater = LayoutInflater.from(getContext());
            convertView = inflater.inflate(...);
        }
    }
    
    
  • Re: Cambia font listView contenuta in un arrayAdapter

    Della finalmente la listview compare con il font che ho scelto io ... sei grande comunque!!! Però è sorto un'altro problema ahahahah , ti posto il codice che ho modificato:
    @Override
        public View getView(int position, View convertView, ViewGroup parent) {
    
           
            if (convertView==null)
            {
                convertView=LayoutInflater.from(getContext()).inflate(R.layout.layout_riga, null);
            }
    
    
    
    
            // ottenere i riferimenti alle singole sub-view che compongono la riga
            testo = (TextView) convertView.findViewById(R.id.testoRiga);
    
            // impostare il font desiderato nelle sub-view
    
            font = Typeface.createFromAsset(getContext().getAssets(), "Quattrocento.ttf");
            testo.setTypeface(font);
    
            // riempire le sub-view con i dati di interesse
            testo.setText("random text");
            // restituire la view corrispondente alla riga
            return convertView;
    
    
        }
    Il problema sorge quando riempio la sub-vien con i dati di interesse...anzichè ottenere i dati che vado a parsare, compare ad ogni riga la scritta "random text" come è pur logico che sia.
    Ora la mia domanda è: quando vado nell'altra activity dove utilizzo il CustomAdapter
    CustomAdapter adapter1 = new CustomAdapter(Seconda.this, R.layout.layout_riga, R.id.testoRiga, titoli);
                date1.setAdapter(adapter1);
    io gli passo come ultimo parametro "titoli" che è il mio arrayList di stringhe. Non dovrebbe convertirlo lui automaticamente e sostituire le stringhe con i dati corretti?
Devi accedere o registrarti per scrivere nel forum
22 risposte