Semplice esempio di Android RecyclerView


170

Ho fatto un elenco di elementi un paio di volte usando Android RecyclerView, ma è un processo piuttosto complicato. Passando attraverso uno dei numerosi tutorial online funziona ( questo , questo e questo sono buoni), ma sto cercando un esempio di ossa nude che posso copiare e incollare per iniziare rapidamente. Sono necessarie solo le seguenti funzionalità:

  • Layout verticale
  • Un singolo TextView su ogni riga
  • Risponde agli eventi clic

Poiché l'ho desiderato più volte, ho finalmente deciso di dare la risposta di seguito per il mio riferimento futuro e il vostro.




1
Per i futuri ragazzi, qui ho scritto un articolo dettagliato con video tutorial handyopinion.com/…
Asad Ali Choudhry

youtu.be/UZwiKdrm768 : puoi dare un'occhiata a questo tutorial video che spiega in dettaglio sulla vista del riciclo:
chandu vutukuri,

Risposte:


387

Di seguito è riportato un esempio minimo che sarà simile alla seguente immagine.

RecyclerView con un elenco di nomi di animali

Inizia con un'attività vuota. Eseguirai le seguenti attività per aggiungere RecyclerView. Tutto quello che devi fare è copiare e incollare il codice in ogni sezione. Successivamente puoi personalizzarlo in base alle tue esigenze.

  • Aggiungi dipendenze per classificare
  • Aggiungi i file di layout xml per l'attività e per la riga RecyclerView
  • Crea l'adattatore RecyclerView
  • Inizializza RecyclerView nella tua attività

Aggiorna dipendenze Gradle

Assicurarsi che le seguenti dipendenze siano nel gradle.buildfile dell'app :

implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'

È possibile aggiornare i numeri di versione a quelli più attuali . Usa compilepiuttosto che implementationse stai ancora usando Android Studio 2.x.

Crea layout attività

Aggiungi il RecyclerViewal tuo layout xml.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rvAnimals"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

Crea layout di riga

Ogni riga nel nostro RecyclerViewavrà solo un singolo TextView. Crea un nuovo file di risorse di layout.

recyclerview_row.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="10dp">

    <TextView
        android:id="@+id/tvAnimalName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"/>

</LinearLayout>

Crea l'adattatore

È RecyclerViewnecessario un adattatore per popolare le viste in ogni riga con i tuoi dati. Crea un nuovo file java.

MyRecyclerViewAdapter.java

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> {

    private List<String> mData;
    private LayoutInflater mInflater;
    private ItemClickListener mClickListener;

    // data is passed into the constructor
    MyRecyclerViewAdapter(Context context, List<String> data) {
        this.mInflater = LayoutInflater.from(context);
        this.mData = data;
    }

    // inflates the row layout from xml when needed
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = mInflater.inflate(R.layout.recyclerview_row, parent, false);
        return new ViewHolder(view);
    }

    // binds the data to the TextView in each row
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        String animal = mData.get(position);
        holder.myTextView.setText(animal);
    }

    // total number of rows
    @Override
    public int getItemCount() {
        return mData.size();
    }


    // stores and recycles views as they are scrolled off screen
    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        TextView myTextView;

        ViewHolder(View itemView) {
            super(itemView);
            myTextView = itemView.findViewById(R.id.tvAnimalName);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
        }
    }

    // convenience method for getting data at click position
    String getItem(int id) {
        return mData.get(id);
    }

    // allows clicks events to be caught
    void setClickListener(ItemClickListener itemClickListener) {
        this.mClickListener = itemClickListener;
    }

    // parent activity will implement this method to respond to click events
    public interface ItemClickListener {
        void onItemClick(View view, int position);
    }
}

Appunti

  • Sebbene non strettamente necessario, ho incluso la funzionalità per l'ascolto degli eventi clic sulle righe. Questo era disponibile nel vecchio ListViewsed è un bisogno comune. Puoi rimuovere questo codice se non ti serve.

Inizializza RecyclerView in Activity

Aggiungi il seguente codice alla tua attività principale.

MainActivity.java

public class MainActivity extends AppCompatActivity implements MyRecyclerViewAdapter.ItemClickListener {

    MyRecyclerViewAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // data to populate the RecyclerView with
        ArrayList<String> animalNames = new ArrayList<>();
        animalNames.add("Horse");
        animalNames.add("Cow");
        animalNames.add("Camel");
        animalNames.add("Sheep");
        animalNames.add("Goat");

        // set up the RecyclerView
        RecyclerView recyclerView = findViewById(R.id.rvAnimals);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        adapter = new MyRecyclerViewAdapter(this, animalNames);
        adapter.setClickListener(this);
        recyclerView.setAdapter(adapter);
    }

    @Override
    public void onItemClick(View view, int position) {
        Toast.makeText(this, "You clicked " + adapter.getItem(position) + " on row number " + position, Toast.LENGTH_SHORT).show();
    }
}

Appunti

  • Si noti che l'attività implementa ItemClickListenerciò che abbiamo definito nel nostro adattatore. Questo ci consente di gestire gli eventi di clic delle righe in onItemClick.

Finito

Questo è tutto. Dovresti essere in grado di eseguire il tuo progetto ora e ottenere qualcosa di simile all'immagine in alto.

Continua

Aggiunta di un divisore tra le righe

Puoi aggiungere un semplice divisore come questo

DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
    layoutManager.getOrientation());
recyclerView.addItemDecoration(dividerItemDecoration);

Se vuoi qualcosa di un po 'più complesso, vedi le seguenti risposte:

Modifica del colore della riga al clic

Vedi questa risposta per sapere come cambiare il colore di sfondo e aggiungere l'effetto ondulazione quando si fa clic su una riga.

Inserisci un singolo articolo

Aggiornamento delle righe

Vedi questa risposta per come aggiungere, rimuovere e aggiornare le righe.

Inserisci un singolo articolo

Ulteriori letture


1
Molto bella. Questo funziona finché non aggiungo un pulsante e provo a impostare il suo listener di clic. Qualche idea sul perché ciò possa interferire?
john ktejik,

1
@johnktejik, è difficile sapere esattamente di cosa stai parlando dalle informazioni fornite qui. Probabilmente sarebbe meglio fare una nuova domanda. La mia ipotesi è che il tuo pulsante gestisca l'evento motion in modo che altre cose non lo capiscano.
Suragch

1
scusa .. per aggiungere la descrizione dell'animale? ES: Cammello nel nuovo TextView: è un animale // Pecora nel nuovo TextVire: è un animale. Ho bisogno di aiuto .. T_T
Montse Mkd,

2
@coder, prego. Sì, l'ho usato per l'output orizzontale e funziona allo stesso modo.
Suragch,

4
Questa risposta necessita di un aggiornamento per androidx.
Jose Alcérreca,

7

Vista Minimal Recycler pronta all'uso modello Kotlin per:

  • Layout verticale
  • Un singolo TextView su ogni riga
  • Risponde agli eventi clic (Single e LongPress)

So che questo è un vecchio thread e così sono le risposte qui. Aggiunta di questa risposta per riferimento futuro:

Aggiungi una vista di riciclo nel layout

   <android.support.v7.widget.RecyclerView
            android:id="@+id/wifiList"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
           /> 

Crea un layout per visualizzare gli elementi dell'elenco (list_item.xml)

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <LinearLayout
        android:padding="5dp"
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_height="wrap_content">

        <android.support.v7.widget.AppCompatTextView
            android:id="@+id/ssid"
            android:text="@string/app_name"
            android:layout_width="match_parent"
            android:textSize="17sp"
            android:layout_height="wrap_content" />

    </LinearLayout>

</android.support.v7.widget.CardView>

Ora crea un adattatore minimo per contenere i dati, il codice qui è autoesplicativo

 class WifiAdapter(private val wifiList: ArrayList<ScanResult>) : RecyclerView.Adapter<WifiAdapter.ViewHolder>() {

     // holder class to hold reference
    inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        //get view reference
        var ssid: TextView = view.findViewById(R.id.ssid) as TextView
    }

     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
         // create view holder to hold reference
         return ViewHolder( LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false))
     }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        //set values
        holder.ssid.text =  wifiList[position].SSID
    }

    override fun getItemCount(): Int {
        return wifiList.size
    }
      // update your data
     fun updateData(scanResult: ArrayList<ScanResult>) {
         wifiList.clear()
         notifyDataSetChanged()
         wifiList.addAll(scanResult)
         notifyDataSetChanged()

     }
 }

Aggiungi questa classe per gestire gli eventi Clic singolo e clic lungo sugli elementi dell'elenco

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

public class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {

    public interface ClickListener {
        void onClick(View view, int position);

        void onLongClick(View view, RecyclerView recyclerView, int position);

    }
    private GestureDetector gestureDetector;
    private ClickListener clickListener;

    public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener) {
        this.clickListener = clickListener;
        gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }

            @Override
            public void onLongPress(MotionEvent e) {
                View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
                if (child != null && clickListener != null) {
                    clickListener.onLongClick(child,recyclerView,  recyclerView.getChildPosition(child));
                }
            }
        });
    }


    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        View child = rv.findChildViewUnder(e.getX(), e.getY());
        if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
            clickListener.onClick(child, rv.getChildPosition(child));
        }
        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {

    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }

Infine, imposta l'adattatore su Vista riciclatore e aggiungi Touch Listener per iniziare a intercettare l'evento touch per il tocco singolo o doppio sulle voci dell'elenco

    wifiAdapter = WifiAdapter(ArrayList())

    wifiList.apply {
        // vertical layout
        layoutManager = LinearLayoutManager(applicationContext)
        // set adapter
        adapter = wifiAdapter

        // Touch handling
        wifiList.addOnItemTouchListener(RecyclerTouchListener(applicationContext, wifiList, object : RecyclerTouchListener.ClickListener {
            override fun onClick(view: View?, position: Int) {
                Toast.makeText(applicationContext, "RV OnCLickj " + position, Toast.LENGTH_SHORT).show()
            }

            override fun onLongClick(view: View, recyclerView: RecyclerView, position: Int) {
                Toast.makeText(applicationContext, "RV OnLongCLickj " + position, Toast.LENGTH_SHORT).show()
            }
        }
        ))
    }

Bonus; Aggiorna dati

wifiAdapter.updateData(mScanResults as ArrayList<ScanResult>)

Risultato:

inserisci qui la descrizione dell'immagine


6

Questa sarà la versione più semplice dell'implementazione di RecyclerView.

inserisci qui la descrizione dell'immagine

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/recycler_view"/>

</FrameLayout>

list_item_view.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="46dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textview"
        android:text="TextView"
        android:textSize="16dp" />

</LinearLayout>

CustomAdapter.java

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
  private List<String> data;
  public CustomAdapter (List<String> data){
    this.data = data;
  }

  @Override
  public CustomAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View rowItem = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_view, parent, false);
    return new ViewHolder(rowItem);
  }

  @Override
  public void onBindViewHolder(CustomAdapter.ViewHolder holder, int position) {
    holder.textView.setText(this.data.get(position));
  }

  @Override
  public int getItemCount() {
    return this.data.size();
  }

  public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    private TextView textView;

    public ViewHolder(View view) {
      super(view);
      view.setOnClickListener(this);
      this.textView = view.findViewById(R.id.textview);
    }

    @Override
    public void onClick(View view) {
      Toast.makeText(view.getContext(), "position : " + getLayoutPosition() + " text : " + this.textView.getText(), Toast.LENGTH_SHORT).show();
    }
  }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    RecyclerView recyclerView = findViewById(R.id.recycler_view);
    
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setAdapter(new CustomAdapter(generateData()));
    recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
  }

  private List<String> generateData() {
    List<String> data = new ArrayList<>();
    for (int i = 0; i < 100; i++) {
      data.add(String.valueOf(i) + "th Element");
    }
    return data;
  }

}

5

Android RecyclerView

Inizia aggiungendo la libreria recyclerview.

implementation 'androidx.recyclerview:recyclerview:1.1.0'

Crea una classe di modello.

     public class UserModel implements Serializable {

    private String userName;


    public UserModel(String userName) {
        this.userName = userName;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
   }

creare la classe dell'adattatore.

public class UsersAdapter extends RecyclerView.Adapter<UsersAdapter.UsersAdapterVh> implements Filterable {

    private List<UserModel> userModelList;
    private List<UserModel> getUserModelListFiltered;
    private Context context;
    private SelectedUser selectedUser;

    public UsersAdapter(List<UserModel> userModelList,SelectedUser selectedUser) {
        this.userModelList = userModelList;
        this.getUserModelListFiltered = userModelList;
        this.selectedUser = selectedUser;
    }

    @NonNull
    @Override
    public UsersAdapter.UsersAdapterVh onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        context = parent.getContext();

        return new UsersAdapterVh(LayoutInflater.from(context).inflate(R.layout.row_users,null));
    }

    @Override
    public void onBindViewHolder(@NonNull UsersAdapter.UsersAdapterVh holder, int position) {

        UserModel userModel = userModelList.get(position);

        String username = userModel.getUserName();
        String prefix = userModel.getUserName().substring(0,1);

        holder.tvUsername.setText(username);
        holder.tvPrefix.setText(prefix);

    }

    @Override
    public int getItemCount() {
        return userModelList.size();
    }

    @Override
    public Filter getFilter() {

        Filter filter = new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {
                FilterResults filterResults = new FilterResults();

                if(charSequence == null | charSequence.length() == 0){
                    filterResults.count = getUserModelListFiltered.size();
                    filterResults.values = getUserModelListFiltered;

                }else{
                    String searchChr = charSequence.toString().toLowerCase();

                    List<UserModel> resultData = new ArrayList<>();

                    for(UserModel userModel: getUserModelListFiltered){
                        if(userModel.getUserName().toLowerCase().contains(searchChr)){
                            resultData.add(userModel);
                        }
                    }
                    filterResults.count = resultData.size();
                    filterResults.values = resultData;

                }

                return filterResults;
            }

            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) {

                userModelList = (List<UserModel>) filterResults.values;
                notifyDataSetChanged();

            }
        };
        return filter;
    }


    public interface SelectedUser{

        void selectedUser(UserModel userModel);

    }

    public class UsersAdapterVh extends RecyclerView.ViewHolder {

        TextView tvPrefix;
        TextView tvUsername;
        ImageView imIcon;
        public UsersAdapterVh(@NonNull View itemView) {
            super(itemView);
            tvPrefix = itemView.findViewById(R.id.prefix);
            tvUsername = itemView.findViewById(R.id.username);
            imIcon = itemView.findViewById(R.id.imageView);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    selectedUser.selectedUser(userModelList.get(getAdapterPosition()));
                }
            });


        }
    }
}

crea layout row_uses.xml

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:layout_width="match_parent"
        android:padding="10dp"
        android:layout_height="wrap_content">

        <RelativeLayout
            android:layout_width="50dp"
            android:background="@drawable/users_bg"
            android:layout_height="50dp">
            <TextView
                android:id="@+id/prefix"
                android:layout_width="wrap_content"
                android:textSize="16sp"
                android:textColor="@color/headerColor"
                android:text="T"
                android:layout_centerInParent="true"
                android:layout_height="wrap_content"/>

        </RelativeLayout>
        <TextView
            android:id="@+id/username"
            android:layout_width="wrap_content"
            android:textSize="16sp"
            android:textColor="@color/headerColor"
            android:text="username"
            android:layout_marginStart="90dp"
            android:layout_centerVertical="true"
            android:layout_height="wrap_content"/>
        <ImageView
            android:layout_width="wrap_content"
            android:id="@+id/imageView"
            android:layout_margin="10dp"
            android:layout_alignParentEnd="true"
            android:src="@drawable/ic_navigate_next_black_24dp"
            android:layout_height="wrap_content"/>
    </RelativeLayout>

</LinearLayout>

Trova recyclerview e popola i dati.

Toolbar toolbar;
RecyclerView recyclerView;

List<UserModel> userModelList = new ArrayList<>();

String[] names = {"Richard","Alice","Hannah","David"};

UsersAdapter usersAdapter;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    recyclerView = findViewById(R.id.recyclerview);
    toolbar = findViewById(R.id.toolbar);

    this.setSupportActionBar(toolbar);
    this.getSupportActionBar().setTitle("");

    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL));

    for(String s:names){
        UserModel userModel = new UserModel(s);

        userModelList.add(userModel);
    }

    usersAdapter = new UsersAdapter(userModelList,this);

    recyclerView.setAdapter(usersAdapter);

}

trova il tutorial completo e il codice sorgente qui:

Android RecyclerView


Perché si invia il contesto alla classe dell'adattatore utente usersAdapter = new UsersAdapter(userModelList,this);?
Omar Boshra,

4

Sulla base di diverse fonti ho creato l'implementazione semplice di RecyclerView utilizzando una libreria semplice.

Aggiungi questa linea build.gradle

implementation 'com.hereshem.lib:awesomelib:2.0.1'

Aggiungi Crea un RecyclerView aggiungendo MyRecyclerView in activity_main.xml con

<com.hereshem.lib.recycler.MyRecyclerView
        android:id="@+id/recycler"
        app:layoutManager="LinearLayoutManager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

Ora in MainActivity, crea un ViewHolder passando il nome della classe che deve associare

public static class EVHolder extends MyViewHolder<Events> {
    TextView date, title, summary;
    public EVHolder(View v) {
        super(v);
        date = v.findViewById(R.id.date);
        title = v.findViewById(R.id.title);
        summary = v.findViewById(R.id.summary);
    }
    @Override
    public void bindView(Events c) {
        date.setText(c.date);
        title.setText(c.title);
        summary.setText(c.summary);
    }
}

Crea una variabile dell'elenco di elementi e adattatori con pochissime righe passando elementi, classe e layout nell'adattatore

List<Events> items = new ArrayList<>();
MyRecyclerView recycler = findViewById(R.id.recycler);
RecyclerViewAdapter adapter = new RecyclerViewAdapter(this, items, EVHolder.class, R.layout.row_event);
recycler.setAdapter(adapter);

ClickListener può essere aggiunto con le seguenti righe

recycler.setOnItemClickListener(new MyRecyclerView.OnItemClickListener() {
    @Override
    public void onItemClick(int position) {
        Toast.makeText(MainActivity.this, "Recycler Item Clicked " + position, Toast.LENGTH_SHORT).show();
    }
});

È tutto fatto.

Altri esempi e implementazioni sono disponibili qui . Spero che questo ti aiuti !!!


1
cos'è l'attività singola
john ktejik,

1
: errore: impossibile trovare il riepilogo dei simboli = v.findViewById (R.id.summary); ^ simbolo: posizione di riepilogo variabile: ID classe EVHolder.java:15: errore: il metodo non sostituisce o implementa un metodo da un supertipo @Override ^ EVHolder.java:17: errore: impossibile trovare il simbolo date.setText (c.date) ;
john ktejik,

1
@johnktejik R.id.summary è l'id fornito per il file di risorse del layout. si prega di consultare questo file di layout github.com/hereshem/Easy-RecyclerView-Library/blob/master/app/…
Hem Shrestha,

3

Ora hai bisogno di 1 adattatore per tuttiRecyclerView

  • È possibile utilizzare un adattatore per tutti RecyclerView. Quindi NO onBindViewHolder , nessuna onCreateViewHolder manipolazione.
  • Nessun codice per l'impostazione dell'adattatore dalla classe Java / Kotlin. Controlla la classe di esempio .
  • È possibile impostare eventi e dati personalizzati per ogni elenco utilizzando gli adattatori di associazione .

immagine dello schermo

Vi mostro qui impostando due diversi RecyclerViewper 1 adattatore -

activity_home.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <variable
            name="listOne"
            type="java.util.List"/>

        <variable
            name="listTwo"
            type="java.util.List"/>

        <variable
            name="onItemClickListenerOne"
            type="com.ks.nestedrecyclerbindingexample.callbacks.OnItemClickListener"/>

        <variable
            name="onItemClickListenerTwo"
            type="com.ks.nestedrecyclerbindingexample.callbacks.OnItemClickListener"/>

    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <android.support.v7.widget.RecyclerView
            rvItemLayout="@{@layout/row_one}"
            rvList="@{listOne}"
            rvOnItemClick="@{onItemClickListenerOne}"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layoutManager="android.support.v7.widget.LinearLayoutManager"
            />

        <android.support.v7.widget.RecyclerView
            rvItemLayout="@{@layout/row_two}"
            rvList="@{listTwo}"
            rvOnItemClick="@{onItemClickListenerTwo}"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layoutManager="android.support.v7.widget.LinearLayoutManager"
            />

    </LinearLayout>

</layout>

Puoi vedere Elenco passaggi, ID layout elemento e listener clic dal layout.

rvItemLayout="@{@layout/row_one}"
rvList="@{listOne}"
rvOnItemClick="@{onItemClickListenerOne}"

Questi attributi personalizzati sono creati da BindingAdapter .

public class BindingAdapters {
    @BindingAdapter(value = {"rvItemLayout", "rvList", "rvOnItemClick"}, requireAll = false)
    public static void setRvAdapter(RecyclerView recyclerView, int rvItemLayout, List rvList, @Nullable OnItemClickListener onItemClickListener) {
        if (rvItemLayout != 0 && rvList != null && rvList.size() > 0)
            recyclerView.setAdapter(new GeneralAdapter(rvItemLayout, rvList, onItemClickListener));
    }
}

Ora da Activity, passi la lista, fai clic su listener come

HomeActivity.java

public class HomeActivity extends AppCompatActivity {
    ActivityHomeBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_home);
        binding.setListOne(new ArrayList()); // pass your list or set list from response of API
        binding.setListTwo(new ArrayList());
        binding.setOnItemClickListenerOne(new OnItemClickListener() {
            @Override
            public void onItemClick(View view, Object object) {
                if (object instanceof ModelParent) {
                    // TODO: your action here
                }
            }
        });
        binding.setOnItemClickListenerTwo(new OnItemClickListener() {
            @Override
            public void onItemClick(View view, Object object) {
                if (object instanceof ModelChild) {
                    // TODO: your action here  
                }
            }
        });
    }
}

Non vuoi leggere troppo, clonare / scaricare direttamente l'esempio completo dal mio repository github. E provalo tu stesso.

Puoi vedere GeneralAdapter.javanel repository sopra.

In caso di problemi durante l'impostazione dell'associazione dei dati, vedere questa risposta .


2

Dato che non posso ancora commentare, pubblicherò come risposta il link .. Ho trovato un tutorial semplice e ben organizzato su recyclerview http://www.androiddeft.com/2017/10/01/recyclerview-android/

A parte questo, quando hai intenzione di aggiungere una vista del riciclatore alla tua attività, quello che vuoi fare è come sotto e come dovresti farlo è stato descritto sul link

  • aggiungi il componente RecyclerView nel tuo file di layout
  • crea una classe che visualizzerai come righe di elenco
  • crea un file di layout che è il layout di una riga del tuo elenco
  • ora abbiamo bisogno di un adattatore personalizzato, quindi crea un adattatore personalizzato estendendolo dalla classe padre RecyclerView.Adapter
  • aggiungi recyclerview nel tuo mainActivity oncreate
  • aggiunta di separatori
  • aggiungendo ascoltatori Touch

2

È possibile utilizzare l'adattatore astratto con programmi di utilità diff e filtro

SimpleAbstractAdapter.kt

abstract class SimpleAbstractAdapter<T>(private var items: ArrayList<T> = arrayListOf()) : RecyclerView.Adapter<SimpleAbstractAdapter.VH>() {
   protected var listener: OnViewHolderListener<T>? = null
   private val filter = ArrayFilter()
   private val lock = Any()
   protected abstract fun getLayout(): Int
   protected abstract fun bindView(item: T, viewHolder: VH)
   protected abstract fun getDiffCallback(): DiffCallback<T>?
   private var onFilterObjectCallback: OnFilterObjectCallback? = null
   private var constraint: CharSequence? = ""

override fun onBindViewHolder(vh: VH, position: Int) {
    getItem(position)?.let { bindView(it, vh) }
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
    return VH(parent, getLayout())
}

override fun getItemCount(): Int = items.size

protected abstract class DiffCallback<T> : DiffUtil.Callback() {
    private val mOldItems = ArrayList<T>()
    private val mNewItems = ArrayList<T>()

    fun setItems(oldItems: List<T>, newItems: List<T>) {
        mOldItems.clear()
        mOldItems.addAll(oldItems)
        mNewItems.clear()
        mNewItems.addAll(newItems)
    }

    override fun getOldListSize(): Int {
        return mOldItems.size
    }

    override fun getNewListSize(): Int {
        return mNewItems.size
    }

    override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
        return areItemsTheSame(
                mOldItems[oldItemPosition],
                mNewItems[newItemPosition]
        )
    }

    abstract fun areItemsTheSame(oldItem: T, newItem: T): Boolean

    override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
        return areContentsTheSame(
                mOldItems[oldItemPosition],
                mNewItems[newItemPosition]
        )
    }

    abstract fun areContentsTheSame(oldItem: T, newItem: T): Boolean
}

class VH(parent: ViewGroup, @LayoutRes layout: Int) : RecyclerView.ViewHolder(LayoutInflater.from(parent.context).inflate(layout, parent, false))

interface OnViewHolderListener<T> {
    fun onItemClick(position: Int, item: T)
}

fun getItem(position: Int): T? {
    return items.getOrNull(position)
}

fun getItems(): ArrayList<T> {
    return items
}

fun setViewHolderListener(listener: OnViewHolderListener<T>) {
    this.listener = listener
}

fun addAll(list: List<T>) {
    val diffCallback = getDiffCallback()
    when {
        diffCallback != null && !items.isEmpty() -> {
            diffCallback.setItems(items, list)
            val diffResult = DiffUtil.calculateDiff(diffCallback)
            items.clear()
            items.addAll(list)
            diffResult.dispatchUpdatesTo(this)
        }
        diffCallback == null && !items.isEmpty() -> {
            items.clear()
            items.addAll(list)
            notifyDataSetChanged()
        }
        else -> {
            items.addAll(list)
            notifyDataSetChanged()
        }
    }
}

fun add(item: T) {
    items.add(item)
    notifyDataSetChanged()
}

fun add(position:Int, item: T) {
    items.add(position,item)
    notifyItemInserted(position)
}

fun remove(position: Int) {
    items.removeAt(position)
    notifyItemRemoved(position)
}

fun remove(item: T) {
    items.remove(item)
    notifyDataSetChanged()
}

fun clear(notify: Boolean=false) {
    items.clear()
    if (notify) {
        notifyDataSetChanged()
    }
}

fun setFilter(filter: SimpleAdapterFilter<T>): ArrayFilter {
    return this.filter.setFilter(filter)
}

interface SimpleAdapterFilter<T> {
    fun onFilterItem(contains: CharSequence, item: T): Boolean
}

fun convertResultToString(resultValue: Any): CharSequence {
    return filter.convertResultToString(resultValue)
}

fun filter(constraint: CharSequence) {
    this.constraint = constraint
    filter.filter(constraint)
}

fun filter(constraint: CharSequence, listener: Filter.FilterListener) {
    this.constraint = constraint
    filter.filter(constraint, listener)
}

fun getFilter(): Filter {
    return filter
}

interface OnFilterObjectCallback {
    fun handle(countFilterObject: Int)
}

fun setOnFilterObjectCallback(objectCallback: OnFilterObjectCallback) {
    onFilterObjectCallback = objectCallback
}

inner class ArrayFilter : Filter() {
    private var original: ArrayList<T> = arrayListOf()
    private var filter: SimpleAdapterFilter<T> = DefaultFilter()
    private var list: ArrayList<T> = arrayListOf()
    private var values: ArrayList<T> = arrayListOf()


    fun setFilter(filter: SimpleAdapterFilter<T>): ArrayFilter {
        original = items
        this.filter = filter
        return this
    }

    override fun performFiltering(constraint: CharSequence?): Filter.FilterResults {
        val results = Filter.FilterResults()
        if (constraint == null || constraint.isBlank()) {
            synchronized(lock) {
                list = original
            }
            results.values = list
            results.count = list.size
        } else {
            synchronized(lock) {
                values = original
            }
            val result = ArrayList<T>()
            for (value in values) {
                if (constraint!=null && constraint.trim().isNotEmpty() && value != null) {
                    if (filter.onFilterItem(constraint, value)) {
                        result.add(value)
                    }
                } else {
                    value?.let { result.add(it) }
                }
            }
            results.values = result
            results.count = result.size
        }
        return results
    }

    override fun publishResults(constraint: CharSequence, results: Filter.FilterResults) {
        items = results.values as? ArrayList<T> ?: arrayListOf()
        notifyDataSetChanged()
        onFilterObjectCallback?.handle(results.count)
    }

}

class DefaultFilter<T> : SimpleAdapterFilter<T> {
    override fun onFilterItem(contains: CharSequence, item: T): Boolean {
        val valueText = item.toString().toLowerCase()
        if (valueText.startsWith(contains.toString())) {
            return true
        } else {
            val words = valueText.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
            for (word in words) {
                if (word.contains(contains)) {
                    return true
                }
            }
        }
        return false
    }
  }
}

Estendi l'adattatore astratto con i metodi degli attrezzi

TasksAdapter.kt

import android.annotation.SuppressLint
  import kotlinx.android.synthetic.main.task_item_layout.view.*

class TasksAdapter(private val listener:TasksListener? = null) : SimpleAbstractAdapter<Task>() {
override fun getLayout(): Int {
    return R.layout.task_item_layout
}

override fun getDiffCallback(): DiffCallback<Task>? {
    return object : DiffCallback<Task>() {
        override fun areItemsTheSame(oldItem: Task, newItem: Task): Boolean {
            return oldItem.id == newItem.id
        }

        override fun areContentsTheSame(oldItem: Task, newItem: Task): Boolean {
            return oldItem.items == newItem.items
        }
    }
}

@SuppressLint("SetTextI18n")
override fun bindView(item: Task, viewHolder: VH) {
    viewHolder.itemView.apply {
        val position = viewHolder.adapterPosition
        val customer = item.customer
        val customerName = if (customer != null) customer.name else ""
        tvTaskCommentTitle.text = customerName + ", #" + item.id
        tvCommentContent.text = item.taskAddress
        ivCall.setOnClickListener {
            listener?.onCallClick(position, item)
        }
        setOnClickListener {
            listener?.onItemClick(position, item)
        }
    }
}

 interface TasksListener : SimpleAbstractAdapter.OnViewHolderListener<Task> {
    fun onCallClick(position: Int, item: Task)
 }
}

Adattatore Init

mAdapter = TasksAdapter(object : TasksAdapter.TasksListener {
            override fun onCallClick(position: Int, item:Task) {
            }

            override fun onItemClick(position: Int, item:Task) {

            }
        })
rvTasks.adapter = mAdapter

e riempire

mAdapter?.addAll(tasks)

aggiungi filtro personalizzato

mAdapter?.setFilter(object : SimpleAbstractAdapter.SimpleAdapterFilter<MoveTask> {
            override fun onFilterItem(contains: CharSequence, item:Task): Boolean {
                return contains.toString().toLowerCase().contains(item.id?.toLowerCase().toString())
            }
    })

filtra i dati

mAdapter?.filter("test")

aggiungi alcune modifiche con diff utils, aggiungi il tipo di supporto gist.github.com/arnyigor/568035c6db9bdbeaf609b68a71834349
Igor Arny,

1

dipendenze

compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support:design:25.3.1'
    compile 'com.android.support:multidex:1.0.1'
    compile 'com.android.support:cardview-v7:25.3.1'
    compile 'com.android.support:support-v4:25.3.1'
    compile 'com.lguipeng.bubbleview:library:1.0.0'
    compile 'com.larswerkman:HoloColorPicker:1.5'
    compile 'com.mcxiaoke.volley:library-aar:1.0.0'

Una classe per l'elemento clic

 import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
    private OnItemClickListener mListener;

    public interface OnItemClickListener {
        public void onItemClick(View view, int position);
    }

    GestureDetector mGestureDetector;

    public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
        mListener = listener;
        mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }
        });
    }

    @Override
    public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
        View childView = view.findChildViewUnder(e.getX(), e.getY());
        if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
            mListener.onItemClick(childView, view.getChildPosition(childView));
            return true;
        }
        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }


}

RecyclerView di seconda classe

import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;

public class SLByTopics extends Fragment {


    public static ArrayList<MByTopics> byTopicsMainArrayList=new ArrayList<>();


    TabRefreshReceiver tabRefreshReceiver;
    RecyclerView recyclerView;
    SAdpByTopics sAdpByTopics;
    public ArrayList<MByTopics> mByTopicsArrayList=new ArrayList<>();
    ProgressDialog progressDialog;

    public SLByTopics(){
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.sl_fragment_by_topics, container, false);

        progressDialog = new ProgressDialog(getActivity());
        if (IsOnline.isNetworkAvailable(getActivity())) {
            getCategoryTree();
        } else{
            IsOnline.showNoInterNetMessage(getActivity());
        }
        tabRefreshReceiver = new TabRefreshReceiver();
       LocalBroadcastManager.getInstance(getContext()).registerReceiver(tabRefreshReceiver, new IntentFilter("BY_TOPICS"));

        setUpView(view);
        return view;
    }

    private void setUpView(View view) {

        recyclerView=(RecyclerView)view.findViewById(R.id.by_topics_list_recyclerView);
        LinearLayoutManager linearLayoutManager=new LinearLayoutManager(getActivity());
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(linearLayoutManager);
    }

    @Override
    public void onResume() {
        super.onResume();

        recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(getActivity(), new RecyclerItemClickListener.OnItemClickListener() {
            @Override
            public void onItemClick(View view, final int position) {

                if (mByTopicsArrayList.get(position).getChild().size()>0){
                    Intent intent = new Intent(getActivity(), SByTopicCategory.class);
                    intent.putExtra("selectedCategoryName",mByTopicsArrayList.get(position).getCatname());
                    intent.putExtra("jsonData",mByTopicsArrayList.get(position).getMainTopicJson());
                    startActivity(intent);
                    getActivity().overridePendingTransition(R.anim.activity_in, R.anim.activity_out);
                }else {
                    Intent intent = new Intent(getActivity(), SByCategoryQuestionList.class);
                    intent.putExtra("selectedSubCategoryName",mByTopicsArrayList.get(position).getCatname());
                    intent.putExtra("catID",mByTopicsArrayList.get(position).getId());
                    startActivity(intent);
                    getActivity().overridePendingTransition(R.anim.activity_in, R.anim.activity_out);
                }
            }
        }));

    }

    private class TabRefreshReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            try {
                FragmentTransaction ft = getFragmentManager().beginTransaction();
                ft.detach(SLByTopics.this).attach(SLByTopics.this).commit();
                LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(tabRefreshReceiver);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }








    private void getCategoryTree() {
        progressDialog.setMessage("Please Wait...");
        progressDialog.setCancelable(false);
        progressDialog.show();

        StringRequest stringRequest = new StringRequest(Request.Method.POST, Const.HOSTNAME + Const.STUDENT_GET_CATEGORY_TREE,
                new Response.Listener<String>() {
                    @SuppressLint("LongLogTag")
                    @Override
                    public void onResponse(String response) {
                        try {
                            JSONObject object = new JSONObject(response);
                            String status = object.getString("status");
                            int i = Integer.parseInt(status);

                            switch (i) {

                                case 0:
                                    progressDialog.dismiss();
//                                    Toast.makeText(getActivity(), "getCategorySuccess", Toast.LENGTH_SHORT).show();
                                    Log.e("getCategoryTree Response", "getCategoryTree Response : " + response);

                                    try {



                                        byTopicsMainArrayList.clear();
                                        JSONArray info = object.getJSONArray("info");
                                        if (info.length() > 0) {
                                            for (i = 0; i < info.length(); i++) {
                                                JSONObject data = info.getJSONObject(i);
                                                MByTopics mByTopics = new MByTopics();
                                                mByTopics.setId(data.getString("id"));
                                                mByTopics.setCatname(data.getString("catname"));
                                                mByTopics.setMainTopicJson(data.toString());

                                                JSONArray topicChildren = data.getJSONArray("children");
                                                ArrayList<SMByTopicCategory> byChildrenArrayList = new ArrayList<>();

                                                for (int j = 0; j < topicChildren.length(); j++) {
                                                    JSONObject topicChildrenData = topicChildren.getJSONObject(j);
                                                    SMByTopicCategory smByTopicCategory = new SMByTopicCategory();
                                                    smByTopicCategory.setId(topicChildrenData.getString("id"));
                                                    smByTopicCategory.setCatname(topicChildrenData.getString("catname"));
                                                    smByTopicCategory.setChildTopicJson(topicChildrenData.toString());

                                                    JSONArray topicChildrenQuestion = topicChildrenData.getJSONArray("children");
                                                    ArrayList<SMByTopicSubCategory> byChildrenSubArrayList = new ArrayList<>();

                                                    for (int k = 0; k < topicChildrenQuestion.length(); k++) {
                                                        JSONObject topicChildrenSubData = topicChildrenQuestion.getJSONObject(k);
                                                        SMByTopicSubCategory smByTopicSubCategory = new SMByTopicSubCategory();
                                                        smByTopicSubCategory.setId(topicChildrenSubData.getString("id"));
                                                        smByTopicSubCategory.setCatname(topicChildrenSubData.getString("catname"));
                                                        smByTopicSubCategory.setChildSubTopicJson(topicChildrenSubData.toString());

                                                        byChildrenSubArrayList.add(smByTopicSubCategory);
                                                    }

                                                    smByTopicCategory.setQuestions(byChildrenSubArrayList);

                                                    byChildrenArrayList.add(smByTopicCategory);
                                                }
                                                mByTopics.setChild(byChildrenArrayList);
                                                byTopicsMainArrayList.add(mByTopics);
                                            }


                                            mByTopicsArrayList.clear();
                                            mByTopicsArrayList=byTopicsMainArrayList;
                                            sAdpByTopics=new SAdpByTopics(mByTopicsArrayList,getActivity());
                                            recyclerView.setAdapter(sAdpByTopics);
                                            sAdpByTopics.notifyDataSetChanged();

                                        }

                                    }catch (Exception e){
                                        e.printStackTrace();
                                    }
                                    break;

                                default:
                                    progressDialog.dismiss();
//                                    Toast.makeText(getActivity(), "getCategoryError : " + response, Toast.LENGTH_SHORT).show();
                                    Log.e("getCategoryTree Not Response", "getCategoryTree Uploading Not Response : " + response);
                            }

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        progressDialog.dismiss();
                        Log.e("getCategoryTree Error :","getCategoryTree Error :"+error.getMessage());
//                        Toast.makeText(getActivity(), error.getMessage(), Toast.LENGTH_LONG).show();
                    }
                }){

        };/* {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {

                Map<String, String> map = new HashMap<String, String>();
//                map.put("uid", String.valueOf(ConfigManager.getUserId()));
                return map;
            }
        };*/

        stringRequest.setRetryPolicy(new DefaultRetryPolicy(
                0,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

        RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
        requestQueue.add(stringRequest);
    }
}

Classe adattatore per articolo riciclatore

import android.app.Activity;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;

public class SAdpByTopics extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
        ArrayList<MByTopics> topicsArrayList=new ArrayList<>();
        Activity activity;

 public SAdpByTopics(ArrayList<MByTopics> topicsArrayList,Activity activity){
        this.topicsArrayList=topicsArrayList;
        this.activity=activity;
        }

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemeView= LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_by_topic_list,parent,false);
        RecyclerView.ViewHolder holder=new Holder(itemeView);
        holder.setIsRecyclable(false);
        return holder;
        }

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final Holder classHolder = (Holder) holder;
        try{
        classHolder.txt_topic_name.setText(topicsArrayList.get(position).getCatname());
        }catch (Exception e){
        e.printStackTrace();
        }
        }

@Override
public int getItemCount() {
        return topicsArrayList.size();
        }


class Holder extends RecyclerView.ViewHolder implements View.OnClickListener {
    TextView txt_topic_name;

    public Holder(View itemView) {
        super(itemView);
        txt_topic_name = (TextView) itemView.findViewById(R.id.txt_topic_name);
    }

    @Override
    public void onClick(View v) {

    }
}
}

Classe del modulo

public class MByTopics {

    String id;
    String topicName;
    String catname;
    String MainTopicJson;
    ArrayList<SMByTopicCategory> child;
    ArrayList<SMByTopicSubCategory> questions;



    public void setId(String id){
        this.id=id;
    }
    public String getId(){
        return  id;
    }

    public void setCatname(String catname) {
        this.catname = catname;
    }

    public String getCatname() {
        return catname;
    }

    public void setTopicName(String topicName) {
        this.topicName = topicName;
    }
    public String getTopicName() {
        return topicName;
    }

    public void setChild(ArrayList<SMByTopicCategory> child) {
        this.child = child;
    }


    public String getMainTopicJson() {
        return MainTopicJson;
    }

    public void setMainTopicJson(String mainTopicJson) {
        MainTopicJson = mainTopicJson;
    }


    public ArrayList<SMByTopicCategory> getChild() {
        return child;
    }

    public void setQuestions(ArrayList<SMByTopicSubCategory> questions) {
        this.questions = questions;
    }

    public ArrayList<SMByTopicSubCategory> getQuestions() {
        return questions;
    }

    public ArrayList<MByTopics> getByTopicList() {
        ArrayList<MByTopics> mByTopicsArrayList = new ArrayList<>();

        for (int i=0;i<11;i++){
            MByTopics mQuestionBankCategory=new MByTopics();

            if (i==1 || i== 5|| i==9){
                mQuestionBankCategory.setTopicName("Microeconomics");
            }else  if (i==2 || i== 10|| i==6) {
                mQuestionBankCategory.setTopicName("Macroeconomics");
            }else {
                mQuestionBankCategory.setTopicName("Current Isssues");
            }

            mByTopicsArrayList.add(mQuestionBankCategory);
        }

        return mByTopicsArrayList;
    }

}

3
le spiegazioni sarebbero
buone


1

Ecco una soluzione Kotlin molto più recente per questo che è molto più semplice di molte delle risposte scritte qui, usa una classe anonima.

val items = mutableListOf<String>()

inner class ItemHolder(view: View): RecyclerView.ViewHolder(view) {
    var textField: TextView = view.findViewById(android.R.id.text1) as TextView
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    rvitems.layoutManager = LinearLayoutManager(context)
    rvitems.adapter = object : RecyclerView.Adapter<ItemHolder>() {

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemHolder {
            return ItemHolder(LayoutInflater.from(parent.context).inflate(android.R.layout.simple_list_item_1, parent, false))
        }

        override fun getItemCount(): Int {
            return items.size
        }

        override fun onBindViewHolder(holder: ItemHolder, position: Int) {
            holder.textField.text = items[position]
            holder.textField.setOnClickListener {
                Toast.makeText(context, "Clicked $position", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

Mi sono preso la libertà di usare android.R.layout.simple_list_item_1 in quanto è più semplice. Volevo semplificarlo ulteriormente e inserire ItemHolder come classe interna, ma non riuscivo a capire come fare riferimento in un tipo nel parametro della classe esterna.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.