CERCA
PER MODELLO
FullScreen Chatbox! :)

Utente del giorno: gianpassa con ben 1 Thanks ricevuti nelle ultime 24 ore
Utente della settimana: carotix con ben 11 Thanks ricevuti negli ultimi sette giorni
Utente del mese: megthebest con ben 26 Thanks ricevuti nell'ultimo mese

Visualizzazione dei risultati da 1 a 2 su 2
Discussione:

[Medio] RecyclerView, viewholder e adapters

Se questa discussione ti è stata utile, ti preghiamo di lasciare un messaggio di feedback in modo che possa essere preziosa in futuro anche per altri utenti come te!
  1. #1
    Androidiani Power User L'avatar di cesco


    Registrato dal
    Sep 2010
    Località
    Bg
    Messaggi
    5,018
    Smartphone
    TYTN2,desire,desireHD, oneX

    Ringraziamenti
    54
    Ringraziato 1,346 volte in 724 Posts
    Predefinito

    [Medio] RecyclerView, viewholder e adapters

    Tra le nuove API Lollipop e anche nell'ultima versione della support library è disponibile questa view, altamente personalizzabile e che va oltre il semplice concetto di ListView o GridView.
    RecyclerView permette infatti di ottenere praticamente tutte le configurazioni che desideriamo estendendo alcune classi.

    Qui sotto un esempio di implementazione.

    build.gradle

    i

    Queste due librerie vi permetteranno di utilizzare, come ovvio, le nuove API anche su dispositivi pre-lollipop

     
    1
    2
    dependencies {
    3
        compile "com.android.support:appcompat-v7:21.0.+"
    4
        compile 'com.android.support:recyclerview-v7:21.0.+'
    5
    }
    6


    fragment_main.xml

    i

    Un semplice layout contenente solo la nostra RecyclerView

    16
     
    1
    2
    <?xml version="1.0" encoding="utf-8"?>
    3
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    4
        android:layout_width="match_parent"
    5
        android:layout_height="match_parent"
    6
        android:orientation="vertical">
    7
    8
        <android.support.v7.widget.RecyclerView
    9
            android:id="@+id/list_article"
    10
            android:layout_width="match_parent"
    11
            android<img src="//static.androidiani.com/forum/images/smilies/emo_im_tongue_sticking_out.png" border="0" alt="" title="Stick Out Tongue" class="inlineimg" />addingTop="8dp"
    12
            android:clipToPadding="false"
    13
            android:layout_height="match_parent"/>
    14
    15
    </LinearLayout>
    16


    MyFragment.java

    i

    Non implemento tutto il codice relativo al fragment ma solo la parte che ci interessa per la configurazione iniziale della RecyclerView.
    In questo caso specifico io vario la visualizzazione degli elementi in base all'orientazione del dispositivo.
    La RecyclerView fondamentalmente si basa sull'utilizzo di LayoutManagers, per appunto, gestire la visualizzazione degli elementi.
    In questo caso utilizzo un GridLayoutManager, definendo nel costruttore quante colonne dovrà avere la nostra RecyclerView(2);
    Lo step successivo è definire lo SpanSizeLookup, una classe che andremo ad estendere e che sarà necessaria per stabilire quante colonne dovrà occupare la singola riga della lista (in questo caso 1 o 2) [vedi sotto]


    16
     
    1
    2
            @<a rel="nofollow" href="https://www.androidiani.com/forum/members/override.html" target="_blank">Override</a>
    3
        public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
    4
            super.onCreateView(inflater, parent, savedInstanceState);
    5
            View v = inflater.inflate(R.layout.list_article, parent, false);
    6
    7
            mList = (RecyclerView) v.findViewById(R.id.list_article);
    8
            mList.setHasFixedSize(true);
    9
            GridLayoutManager glm = new GridLayoutManager(getActivity(), 2);
    10
            glm.setOrientation(GridLayoutManager.VERTICAL);
    11
            glm.setSpanSizeLookup(new GridSpanSizeLookup(getActivity().getResources().ge  tConfiguration()));
    12
            mList.setLayoutManager(glm);
    13
    14
            return v;
    15
        }
    16


    GridSpanSizeLookup.java

    i

    Volendo cambiare il tipo di visualizzazione in base al cambio di orientazione del dispositivo, nel costruttore della classe passo anche la configurazione del dispositivo e tramite un case statement ritorno il numero di colonne che il singolo elemento deve occupare.

    22
     
    1
    2
    public class GridSpanSizeLookup extends GridLayoutManager.SpanSizeLookup {
    3
    4
        private Configuration mConfig;
    5
    6
        public GridSpanSizeLookup(Configuration config) {
    7
            this.mConfig = config;
    8
        }
    9
    10
            @<a rel="nofollow" href="https://www.androidiani.com/forum/members/override.html" target="_blank">Override</a>
    11
        public int getSpanSize(int i) {
    12
            switch(mConfig.orientation) {
    13
                case Configuration.ORIENTATION_LANDSCAPE:
    14
                    return 1;
    15
                case Configuration.ORIENTATION_PORTRAIT:
    16
                    return 2;
    17
                default:
    18
                    return 2;
    19
            }
    20
        }
    21
    }
    22


    MyViewHolder.java

    i

    Questa classe funziona quasi esattamente come quella che fino ad ora avevamo utilizzato nelle classiche ListView e GridView per questioni di performance.

    20
     
    1
    2
    public class MyViewHolder extends RecyclerView.ViewHolder {
    3
    4
        public TextView title;
    5
        public ImageView image;
    6
        public TextView author;
    7
        public TextView date;
    8
    9
        public MyViewHolder(View v) {
    10
            super(v);
    11
            title = (TextView) v.findViewById(R.id.title);
    12
            image = (ImageView) v.findViewById(R.id.image);
    13
            author = (TextView) v.findViewById(R.id.author);
    14
            date = (TextView) v.findViewById(R.id.date);
    15
            title.setTypeface(Typeface.createFromAsset(v.getCo  ntext().getAssets(), "RobotoSlab-Light.ttf"));
    16
            author.setTypeface(Typeface.createFromAsset(v.getC  ontext().getAssets(), "RobotoSlab-Light.ttf"));
    17
            date.setTypeface(Typeface.createFromAsset(v.getCon  text().getAssets(), "RobotoSlab-Thin.ttf"));
    18
        }
    19
    }
    20


    MyAdapter.java

    i

    Il nostro adapter ora dovrà estendere RecyclerView.Adapter<T>. Il funzionamento è fondamentalmente il medesimo degli altri adapter (Es: BaseAdapter)

    40
     
    1
    2
    public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
    3
    4
        private Context context;
    5
        private ArrayList<Item> items;
    6
    7
        public ArticlesAdapter(Context c, ArrayList<Item> _items) {
    8
            this.context = c;
    9
            this.items = _items;
    10
        }
    11
    12
            @<a rel="nofollow" href="https://www.androidiani.com/forum/members/override.html" target="_blank">Override</a>
    13
        public MyViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    14
            View v = LayoutInflater.from(viewGroup.getContext())
    15
                    .inflate(R.layout.my_list_row, viewGroup, false);
    16
            return new MyViewHolder(v);
    17
        }
    18
    19
            @<a rel="nofollow" href="https://www.androidiani.com/forum/members/override.html" target="_blank">Override</a>
    20
        public void onBindViewHolder(final MyViewHolder myViewHolder, int i) {
    21
            Item it = items.get(i);
    22
    23
            if(it.getImageLink() != null) {
    24
                Picasso.with(context)
    25
                        .load(it.getImageLink())
    26
                        .fit()
    27
                        .centerCrop()
    28
                        .into(myViewHolder.image);
    29
            }
    30
            myViewHolder.author.setText(it.getAuthor());
    31
            myViewHolder.title.setText(it.getTitle());
    32
            myViewHolder.date.setText(dateConvert(it.getDate()  ));
    33
        }
    34
    35
            @<a rel="nofollow" href="https://www.androidiani.com/forum/members/override.html" target="_blank">Override</a>
    36
        public int getItemCount() {
    37
            return items.size();
    38
        }
    39
    }
    40


    MyFragment.java

    i

    Il modo di impostazione dell'adapter non cambia.

    8
     
    1
    2
            @<a rel="nofollow" href="https://www.androidiani.com/forum/members/override.html" target="_blank">Override</a>
    3
        public void onActivityCreated(Bundle savedInstanceState) {
    4
            super.onActivityCreated(savedInstanceState);
    5
            mAdapter = new MyAdapter(getActivity(), items);
    6
            mList.setAdapter(mAdapter);
    7
    }
    8


    Buon coding
    Ultima modifica di cesco; 23-11-14 alle 19:06
    Follow me on:
    <!-- Place this tag where you want the widget to render. -->
    <div class="g-person" data-width="180" data-href="//plus.google.com/113012341277613226011" data-theme="dark" data-rel="author"></div>

    <!-- Place this tag after the last widget tag. -->
    <script type="text/javascript">
    window.___gcfg = {lang: 'it'};

    (function() {
    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'https://apis.google.com/js/plusone.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
    })();
    </script>
    <br>
    <a class="twitter-timeline" href="https://twitter.com/xcesco89" data-widget-id="398762031488040960">Tweets di @xcesco89</a>
    <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementB yId(id)){js=d.createElement(s);js.id=id;js.src=p+" ://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}} (document,"script","twitter-wjs");</script>
    Androidiani app
    Estensione Androidiani per Google Chrome

  2. I seguenti 2 Utenti hanno ringraziato cesco per il post:

    Andrea (24-11-14),lords91 (07-09-15)

  3.  
  4. #2
    Baby Droid


    Registrato dal
    Apr 2015
    Messaggi
    2

    Ringraziamenti
    0
    Ringraziato 0 volte in 0 Posts
    Predefinito

    Mi scuso se non é il posto giusto per chiedere, ma volevo togliermi dei dubbi. In passato ho cercato di realizzare gallerie di immagini con la gridview, non senza diverse difficoltà, e senza ottenere spesso i risultati desiderati. Mi confermate che nell'ottica di un restyle delle suddette conviene puntare sulla RecyclerView? E che grazie le support library non dovrebbero esserci problemi d'incompatibilità all'indietro?
    Grazie!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire risposte
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Torna su
Privacy Policy