web-dev-qa-db-fra.com

Comment afficher une ArrayList dans une RecyclerView?

J'ai besoin d'ajouter un Activity où je peux lister les éléments d'un ArrayList<CustomClass> Et j'ai vu qu'il y a une nouvelle et meilleure façon d'afficher les listes - RecyclerView.

Ma question est de savoir comment implémenter cela dans mon application. J'ai trouvé que j'avais besoin d'utiliser un Adapter, mais je ne comprends pas très bien comment implémenter correctement l'ensemble du processus.

Si vous vous posez la question, je fais référence à ceci des exemples de documents que j'ai lus.

ÉDITER:

Après avoir mis à jour mon code, il dit qu'il ne peut pas résoudre le symbole setOnEntryClickListener:

public class voting extends Activity {


RecyclerView myList;
private ArrayList<Player> players; // Players


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

    Intent intent = this.getIntent();
    Bundle bundle = intent.getExtras();
    players = (ArrayList<Player>)bundle.getSerializable("PLAYERS");

    myList = (RecyclerView) findViewById(R.id.charactersList);
    myList.setLayoutManager(new LinearLayoutManager(this));
    CoursesAdapter adapter = new CoursesAdapter(players);
    myList.setAdapter(adapter);
}

// OR RecyclerView with a click listener

CoursesAdapter clickAdapter = new CoursesAdapter(players);
clickAdapter.setOnEntryClickListener(new CoursesAdapter.OnEntryClickListener() {
    @Override
    public void onEntryClick(View view, int position) {
        // stuff that will happen when a list item is clicked
    }
});
recyclerView.setAdapter(clickAdapter);
}

J'ai donc pensé que j'avais mis ce interface au mauvais endroit (très probablement), en fait je l'ai mis dans la classe Adapter, à la fin, juste après la onAttachedToRecyclerView() Méthode:

    @Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
}


private OnEntryClickListener mOnEntryClickListener;

public interface OnEntryClickListener {
    void onEntryClick(View view, int position);
}

public void setOnEntryClickListener(OnEntryClickListener onEntryClickListener) {
    mOnEntryClickListener = onEntryClickListener;
}



}
9
FET

Je me souviens quand j'ai lu pour la première fois sur RecyclerViews - je suis d'accord que cela peut être un peu déroutant au début. Espérons que cette explication vous aidera à mieux la comprendre.


Principes de base de RecyclerView

1. Ajout de RecyclerView

Vous devez d'abord ajouter votre RecyclerView à votre disposition XML. Je suppose que vous savez comment procéder. Vous le déclarez également dans votre Java:

RecyclerView recyclerView = (RecyclerView) findViewById(R.id.your_recycler_view);

2. Créer le Adapter et comprendre ViewHolder

Ensuite, vous devez créer un Adapter pour cela. Il s'agit d'une classe qui implémente RecyclerView.Adapter<YourAdapter.YourViewHolder>. Je vais expliquer ce que cela signifie dans une minute.

Je crois que cela aide à regarder un exemple de Adapter pour comprendre comment cela fonctionne (par exemple celui que j'ai créé pour une application open-source). Je recommande également fortement de parcourir un ensemble de fichiers Java que j'ai créés comme exemple sur Gist sur GitHub:

https://Gist.github.com/FarbodSalamat-Zadeh/7646564f48ee708c1582c013e1de4f07

Je vais référencer les fichiers d'exemple à partir du lien ci-dessus dans cette explication afin que vous puissiez suivre.

Vous pouvez voir que la classe Adapter contient une classe interne, qui est votre ViewHolder. Par conséquent, il doit étendre RecyclerView.ViewHolder.

À l'intérieur de ce ViewHolder, vous déclarez les variables pour les dispositions qui seront utilisées pour chaque élément de liste dans votre RecyclerView. Dans le constructeur de votre ViewHolder, vous affectez ces variables. Je fais référence à cette partie du code (je donne mon exemple ci-dessous):

    ExampleViewHolder(View itemView) {
        super(itemView);
        text1 = (TextView) itemView.findViewById(R.id.text1);
        text2 = (TextView) itemView.findViewById(R.id.text2);
    }

C'est tout ce dont vous avez besoin pour votre ViewHolder (la classe interne de votre Adapter).

3. Comprendre le Adapter

Comme la plupart des objets Java, vous devrez avoir un constructeur quelques variables privées dans votre classe Adapter. Voici les miennes:

private ArrayList<CustomClass> mCustomObjects;

public ExampleAdapter(ArrayList<CustomClass> arrayList) {
    mCustomObjects = arrayList;
}

Vous devrez avoir votre ArrayList<CustomClass> Comme paramètre constructeur pour pouvoir passer la liste afin que votre Adapter puisse l'utiliser.

Si vous regardez le reste de la classe Adapter, elle contient certaines méthodes qu'elle remplace par ce qu'elle étend. Jetons un coup d'œil à ce que ce sont:

  • getItemCount() renvoie la taille de votre liste.
  • onCreateViewHolder(...) est utilisé pour gonfler la mise en page de votre élément de liste.
  • onBindViewHolder(...) configure vos dispositions pour l'élément de liste (par exemple, en définissant le texte sur TextView)

Dans la plupart des cas, getItemCount() renverra simplement la size() de votre ArrayList<CustomClass>.

La méthode onCreateViewHolder(...) reste généralement la même:

@Override
public ExampleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(Android.R.layout.simple_list_item_2, parent, false);
    return new ExampleViewHolder(view);
}

Vous pouvez voir que je gonfle la mise en page que j'utiliserai comme élément de liste (Android.R.layout.simple_list_item_2). Cette disposition est intégrée à Android donc je n'ai pas besoin de la créer - bien sûr, vous pouvez utiliser la disposition que vous souhaitez, puis modifier votre Adapter pour les widgets que vous Le type de retour de cette méthode correspondra à ce que vous avez nommé votre classe interne ViewHolder.

Maintenant, le bit intéressant est dans onBindViewHolder(...). Vous configurez vos mises en page ici, c'est donc à vous de décider ce que vous voulez faire. Voici un modèle que vous pouvez utiliser:

@Override
public void onBindViewHolder(ExampleViewHolder holder, int position) {
    CustomClass object = mCustomObjects.get(position);

    String firstText = object.getFirstText()
    String secondText = object.getSecondText()

    holder.text1.setText(firstText);
    holder.text2.setText(secondText);
}

Fondamentalement, vous accédez à vos variables ViewHolder (pour les widgets dans la disposition de votre élément de liste) en faisant holder.myWidget. La partie holder provient du paramètre, qui est votre ViewHolder dont nous avons parlé plus tôt, et myWidget serait le nom de la variable View de celle-ci .

Dans l'exemple ci-dessus, le object a une méthode getFirstText(), et le ViewHolder contient un TextView (text1), Donc je suis en train de mettre le texte.

Il existe également une autre méthode - onAttachedToRecyclerView(...). Vous pouvez l'utiliser pour des choses plus complexes, mais au niveau de base, c'est généralement ceci:

@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
}

4. Configuration de RecyclerView

Rappelez-vous au début, lorsque nous avons déclaré et attribué notre RecyclerView?:

RecyclerView recyclerView = (RecyclerView) findViewById(R.id.your_recycler_view);

Maintenant, nous allons le configurer.

Vous commencez par définir un "gestionnaire de mise en page". Cela détermine comment chaque élément de la liste sera affiché à l'écran. Les plus courants sont LinearLayoutManager et GridLayoutManager. Le premier met vos éléments de liste dans une liste standard (rien de spécial en fait, mais c'est très utile), et le second organise vos éléments de liste dans une disposition de type grille.

Dans notre exemple, nous allons utiliser un LinearLayoutManager. Pour définir ceci sur le RecyclerView, nous faisons ceci:

recyclerView.setLayoutManager(new LinearLayoutManager(this));

C'est tout.

Et tout ce que nous avons à faire ensuite est de définir la classe Adapter que nous avons créée et personnalisée plus tôt sur votre RecyclerView:

ExampleAdapter adapter = new ExampleAdapter(yourCustomArrayList);
recyclerView.setAdapter(adapter);

Dans ce qui précède, je suppose que votre adapter n'a qu'un seul paramètre, mais cela dépendra de la façon dont vous l'avez configuré plus tôt.

5. Utilisation de votre RecyclerView

Les étapes ci-dessus devraient vous donner un RecyclerView fonctionnel. Si vous êtes bloqué, vous pouvez voir comment j'en ai ajouté un dans mon application ici .

Vous pouvez également consulter les exemples Google pour l'implémentation RecyclerView .

J'espère que tout cela vous a donné une idée claire du fonctionnement de RecyclerView.


Ajout d'un écouteur de clics

Vous souhaiterez peut-être ajouter un écouteur de clics afin de ne pas utiliser le RecyclerView uniquement pour afficher les éléments.

Pour ce faire, votre classe interne ViewHolder doit implémenter View.OnClickListener. En effet, vous définissez un OnClickListener sur le paramètre itemView du constructeur de ViewHolder. Permettez-moi de vous montrer ce que je veux dire:

public class ExampleClickViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    TextView text1, text2;

    ExampleClickViewHolder(View itemView) {
        super(itemView);

        // we do this because we want to check when an item has been clicked:
        itemView.setOnClickListener(this);

        // now, like before, we assign our View variables
        title = (TextView) itemView.findViewById(R.id.text1);
        subtitle = (TextView) itemView.findViewById(R.id.text2);
    }

    @Override
    public void onClick(View v) {
        // The user may not set a click listener for list items, in which case our listener
        // will be null, so we need to check for this
        if (mOnEntryClickListener != null) {
            mOnEntryClickListener.onEntryClick(v, getLayoutPosition());
        }
    }
}

Les seules autres choses que vous devez ajouter sont une interface personnalisée pour votre Adapter et une méthode de définition:

private OnEntryClickListener mOnEntryClickListener;

public interface OnEntryClickListener {
    void onEntryClick(View view, int position);
}

public void setOnEntryClickListener(OnEntryClickListener onEntryClickListener) {
    mOnEntryClickListener = onEntryClickListener;
}

Ainsi, votre nouveau Adapter prenant en charge les clics est terminé.

Maintenant, utilisons-le ...

    ExampleClickAdapter clickAdapter = new ExampleClickAdapter(yourObjects);
    clickAdapter.setOnEntryClickListener(new ExampleClickAdapter.OnEntryClickListener() {
        @Override
        public void onEntryClick(View view, int position) {
            // stuff that will happen when a list item is clicked
        }
    });
    recyclerView.setAdapter(clickAdapter);

C'est essentiellement la façon dont vous configurez un Adapter normal, sauf que vous utilisez votre méthode de définition que vous avez créée pour contrôler ce que vous ferez lorsque votre utilisateur cliquera sur un élément de liste particulier.


Pour réitérer, vous pouvez regarder à travers un ensemble d'exemples que j'ai faits sur ce Gist sur GitHub:

https://Gist.github.com/FarbodSalamat-Zadeh/7646564f48ee708c1582c013e1de4f07

25

Voici un exemple de travail, j'espère que cela vous aidera:

public class BankListAdapter extends RecyclerView.Adapter<BankListAdapter.BankListViewHolder> {

    ArrayList<BankListModel> bankListModels;
    FragmentActivity activity;
    View selectBank;

    public BankListAdapter(ArrayList<BankListModel> bankListModels, FragmentActivity activity) {
        this.bankListModels=bankListModels;
        this.activity=activity;
    }


    @Override
    public BankListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View bankListLayout = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_bank_list, null);
        BankListViewHolder bankListViewHolder = new BankListViewHolder(bankListLayout);
        return bankListViewHolder;
    }

    @Override
    public void onBindViewHolder(BankListViewHolder holder, int position) {
        holder.bankName.setText(bankListModels.get(position).getBankName());

    }

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

    public class BankListViewHolder extends RecyclerView.ViewHolder {
        TextView bankName;

        public BankListViewHolder(View itemView) {
            super(itemView);
            bankName = (TextView) itemView.findViewById(R.id.tv_bankName);
            selectBank = itemView.findViewById(R.id.cv_selectBank);

        }
    }
}
2
Neo