Kent
Kent

Reputation: 197

Pass multiple parameters to RecyclerView

In my current code, I'm able to pass and display one value to the RecyclerView. I'm not sure what I'm missing or if I have to completely change my code.

Here's my Adapter Class:

public class TechSkillsAdapter extends RecyclerView.Adapter<TrainingViewHolder> {

    Context c;
    ArrayList<String> trainings;

    public TechSkillsAdapter(Context c, ArrayList<String> trainings) {
        this.c = c;
        this.trainings = trainings;
    }

    @Override
    public TrainingViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(c).inflate(R.layout.cv_traininglist, parent, false);
        return new TrainingViewHolder(v);
    }

    @Override
    public void onBindViewHolder(TrainingViewHolder holder, int position) {
        holder.date_txt.setText(trainings.get(position));
    }

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

}

I'm retrieving the list using retrofit then passing the values to a method that displays them to the recyclerview.

Here's how I'm retrieving the trainings:

private void getTraining(final String id, String tid){
        com.trendmicro.projectlara.apis.ApiServiceTraining apiService = ApiClient.getClient().create(ApiServiceTraining.class);
        Call<List<Training>> call = apiService.getMyTraining(id, tid);
        call.enqueue(new Callback<List<Training>>() {
            @Override
            public void onResponse (Call<List<Training>> call, Response<List<Training>> response) {    
                List<Training> training = response.body();
                for(Training t: training){
                    fillTrainings(t.getTraining_title().toString(), t.getTraining_date().toString());
                }
            }

Here's my fillTrainings method.

I'm passing two values but I'm only able to display one value:

private void fillTrainings(String title, String date) {
  training.add(title);

  adapter = new TechSkillsAdapter(getContext(), training);
  rv.setAdapter(adapter);
  progressDialog.dismiss();
}

Here's what I'm trying to fix,I'm not sure how to display the date as well since the way I'm adding the values is: training.add(title);

current list Any help or tip is much appreciated. Thanks!

Upvotes: 1

Views: 2306

Answers (2)

Dennis K
Dennis K

Reputation: 1878

You are receiving a List of Training, but for some reason your adapter is backed by List of String. Why is that?

Modify your adapter to hold Trainings and then bind both the title and the date to the view.

public class TechSkillsAdapter extends RecyclerView.Adapter<TrainingViewHolder> {

    Context c;
    ArrayList<Training> trainings;

    public TechSkillsAdapter(Context c, ArrayList<Training> trainings) {
        this.c = c;
        this.trainings = trainings;
    }

    @Override
    public TrainingViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(c).inflate(R.layout.cv_traininglist, parent, false);
        return new TrainingViewHolder(v);
    }

    @Override
    public void onBindViewHolder(TrainingViewHolder holder, int position) {
        holder.title_txt.setText(trainings.get(position).getTraining_title().toString());
        holder.date_txt.setText(trainings.get(position).getTraining_date().toString());
    }

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

}

And then in your onResponse just do:

    @Override
    public void onResponse (Call<List<Training>> call, Response<List<Training>> response) {    
        List<Training> training = response.body();
        adapter = new TechSkillsAdapter(getContext(), training);
        rv.setAdapter(adapter);
        progressDialog.dismiss();
    }

This should work, but you can improve this if you create and set your adapter once (in onCreate) and pass it some list, and then in onResponse just update that list and do adapter.notifyDataSetChanged() Sort of like this:

//Activity
   List<Training> mTrainingsList = new ArrayList<Training>();

//onCreate
adapter = new TechSkillsAdapter(getContext(), mTrainingsList);
...
}



@Override
public void onResponse (Call<List<Training>> call, Response<List<Training>> response) {    
    List<Training> training = response.body();
    mTrainingList.clear();
    mTrainingList.addAll(training);
    adapter.notifyDatasetChanged();
    progressDialog.dismiss();
}

EDIT: Also, please note that in your code you're going over the list of trainings and you recreate the adapter for each item! Try to avoid this in the future.

Upvotes: 1

ישו אוהב אותך
ישו אוהב אותך

Reputation: 29794

This is because you're recreate the adapter each time you have an item with this code:

@Override
public void onResponse (Call<List<Training>> call, Response<List<Training>> response) {    
    List<Training> training = response.body();
    for(Training t: training){
        // here you're only send one time
        fillTrainings(t.getTraining_title().toString(), t.getTraining_date().toString());
    }
}

You can fix it by sending all the list to your method by changing the method to this:

private void fillTrainings(List<Training> trainList) {
  for(Training train: trainList) {
    training.add(train.getTraining_title().toString());
  }

  adapter = new TechSkillsAdapter(getContext(), training);
  rv.setAdapter(adapter);
  progressDialog.dismiss();
}

then you can use it with:

@Override
public void onResponse (Call<List<Training>> call, Response<List<Training>> response) {    
  List<Training> training = response.body();
  fillTrainings(training);
}

Upvotes: 3

Related Questions