【问题标题】:Pass multiple parameters to RecyclerView向 RecyclerView 传递多个参数
【发布时间】:2018-10-12 01:27:41
【问题描述】:

在我当前的代码中,我能够将一个值传递并显示给 RecyclerView。我不确定我错过了什么,或者我是否必须完全更改我的代码。

这是我的适配器类:

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();
    }

}

我正在使用改造检索列表,然后将值传递给将它们显示到回收视图的方法。

这是我检索培训的方式:

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());
                }
            }

这是我的 fillTrainings 方法。

我传递了两个值,但我只能显示一个值:

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

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

这是我要解决的问题,我不确定如何显示日期,因为我添加值的方式是:training.add(title);

非常感谢任何帮助或提示。谢谢!

【问题讨论】:

    标签: android android-studio arraylist android-recyclerview retrofit2


    【解决方案1】:

    这是因为每次您有一个带有此代码的项目时,您都会重新创建适配器:

    @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());
        }
    }
    

    您可以通过将方法更改为此将所有列表发送到您的方法来修复它:

    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();
    }
    

    然后你可以使用它:

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

    【讨论】:

    • 下面告诉我 List 中的 add() 不能应用于 java.lang.string: private void fillTrainings(List trainList) { for(Training train: trainList) { training.添加(train.getTraining_title().toString()); }
    • 你的training 不是`List'吗?
    【解决方案2】:

    您收到了TrainingList,但由于某种原因,您的适配器受到ListString 的支持。这是为什么呢?

    修改您的适配器以保存培训,然后将标题和日期绑定到视图。

    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();
        }
    
    }
    

    然后在你的 onResponse 中做:

        @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();
        }
    

    这应该可以,但是如果您创建并设置一次适配器(在 onCreate 中)并将其传递一些列表,然后在 onResponse 中更新该列表并执行 adapter.notifyDataSetChanged() 类似这样的操作,则可以改进这一点:

    //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();
    }
    

    编辑:另外,请注意,在您的代码中,您将查看培训列表并为每个项目重新创建适配器!以后尽量避免这种情况。

    【讨论】:

    • 谢谢!我快到了。我收到一个错误:E/RecyclerView:未连接适配器;跳过布局。
    • 我必须调用以下方法来显示列表: private void sortData(boolean asc) { //SORT ARRAY ASCENDING AND DESCENDING if (asc) { // Collections.sort(mTrainingsList); } else { Collections.reverse(mTrainingsList); } 适配器 = 新的 TechSkillsAdapter(getContext(), mTrainingsList); rv.setAdapter(适配器); }
    • 所以为了确保列表出现,我所做的是在改造调用之后添加方法 sortData()。再次感谢丹尼斯的帮助!
    • 酷。但同样,您只需要在创建 Activity 时创建一次适配器,不要在每次获取数据时重新创建它。您会得到“未连接适配器”,因为您需要在实例化它之后调用 rv.setAdapter(adapter)。在您的排序方法中,只需应用排序,然后调用 notifyDatasetChanged
    • 一定会的。再次感谢!
    猜你喜欢
    • 2014-06-02
    • 2016-02-03
    • 2018-06-08
    • 1970-01-01
    • 1970-01-01
    • 2014-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多