【问题标题】:Confused with "Working of onBindViewHolder" in android对 android 中的“onBindViewHolder 的工作”感到困惑
【发布时间】:2020-11-21 15:07:28
【问题描述】:

我是一名初学者,我正在开发一个 Android 项目。我正在创建一个公告选项卡,其中包含字段标题、描述、事件位置、事件时间。 The Idea is Admin 应用程序的管理员将发布一些公告,所有应用程序用户都将收到公告。

在某些情况下,事件字段的位置和时间字段为空。因此,我创建了两个 Cardview 来显示公告。一个有这些字段,另一个没有这两个字段。因此,每当管理员不输入这两个字段时,适配器应切换到第二张卡片视图并应显示在回收器视图上。但是 Recycler 只显示一个视图,即使 Time 和 location 字段不存在。

Snapshot of CardView with All Fields

Snapshot of CardView without Location and Time fields

OnBindViewHolder:

添加了一个布尔标志名称 flagdatelocation 以了解这两个字段是否为空。因此,如果这些字段为空,我将 flagdatelocation 设置为 false,将其传递给 onCreateViewHolder 以便决定选择要选择的卡片视图。我已将 flagdatelocation 声明为类中的全局变量,并使用 true 对其进行初始化。(非静态)

注意:如果我没有启动标志为真,我会得到一个空指针异常。

 boolean flagdateLocation=true;

 protected void onBindViewHolder(@NonNull AnnounceHolder holder, int position, @NonNull Announcements model) {
     holder.textViewTitle.setText(model.getTitle());
     holder.textViewDesc.setText(model.getDescription());
    Log.d(TAG, "onBindViewHolder: "+model.getLocation()+" "+model.getDate());
     if (model.getDate()!=null&&model.getLocation()!=null){
         flagdateLocation = true;
         holder.textViewLocation.setText(model.getLocation());
         holder.textViewDate.setText(model.getDate());

     }
     else{
         flagdateLocation = false;
     }

    Log.d(TAG, "onBindViewHolder: 2"+flagdateLocation);


    String creationDate="";
    Date date = model.getTimestamp();
    if (date != null) {
        DateFormat dateFormat = SimpleDateFormat.getDateInstance(DateFormat.FULL, Locale.US);
        creationDate = dateFormat.format(date);
        Log.d("TAG", creationDate);
    }
     holder.textViewTodayDate.setText(creationDate);

}

OnCreateViewHolder:

我添加了 if Condition 来检查 OnBindViewHolder 中声明的标志,具体取决于这些字段是否为 null,因此选择所需的 Cardview。

public AnnounceHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View V;
   if (flagdateLocation == false) {
       V = LayoutInflater.from(parent.getContext()).inflate(R.layout.announcements_card_view_without_l_s, parent, false);
   }
   else{
       V = LayoutInflater.from(parent.getContext()).inflate(R.layout.announcements_card_view, parent, false);
    }


    return new AnnounceHolder(V);
}

Firebase 结构:

Cloud Firestore where the fields are updated depending on the Admin Announcing

问题是即使字段为空,Recyclerview 始终显示相同的 Cardview。 if 条件不知何故不起作用。我的问题是我的要求方法是正确的,或者需要实施任何其他方式。我哪里错了?

RecylerAdapter 总数:

public class AnnouncementsAdapter extends FirestoreRecyclerAdapter<Announcements, AnnouncementsAdapter.AnnounceHolder> {

boolean flagdateLocation;

public AnnouncementsAdapter(@NonNull FirestoreRecyclerOptions<Announcements> options) {
    super(options);
}

@Override
protected void onBindViewHolder(@NonNull AnnounceHolder holder, int position, @NonNull Announcements model) {
     holder.textViewTitle.setText(model.getTitle());
     holder.textViewDesc.setText(model.getDescription());
    Log.d(TAG, "onBindViewHolder: "+model.getLocation()+" "+model.getDate());
     if (model.getDate()!=null&&model.getLocation()!=null){
         flagdateLocation = true;
         holder.textViewLocation.setText(model.getLocation());
         holder.textViewDate.setText(model.getDate());

     }
     else{
         flagdateLocation = false;
     }

    Log.d(TAG, "onBindViewHolder: 2"+flagdateLocation);


    String creationDate="";
    Date date = model.getTimestamp();
    if (date != null) {
        DateFormat dateFormat = SimpleDateFormat.getDateInstance(DateFormat.FULL, Locale.US);
        creationDate = dateFormat.format(date);
        Log.d("TAG", creationDate);
    }
     holder.textViewTodayDate.setText(creationDate);

}

@NonNull
@Override
public AnnounceHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View V;
   if (flagdateLocation == false) {
       V = LayoutInflater.from(parent.getContext()).inflate(R.layout.announcements_card_view_without_l_s, parent, false);
   }
   else{
      V = LayoutInflater.from(parent.getContext()).inflate(R.layout.announcements_card_view, parent, false);
    }

    V = LayoutInflater.from(parent.getContext()).inflate(R.layout.announcements_card_view, parent, false);


    return new AnnounceHolder(V);
}


class AnnounceHolder extends RecyclerView.ViewHolder{
    TextView textViewTitle;
    TextView textViewDesc;
    TextView textViewLocation;
    TextView textViewDate;
    TextView textViewTodayDate;
    public AnnounceHolder(@NonNull View itemView) {
        super(itemView);
        textViewTitle = itemView.findViewById(R.id.title_announcements);
        textViewDesc = itemView.findViewById(R.id.description_announcements);
        textViewLocation = itemView.findViewById(R.id.location_announcemets);
        textViewDate = itemView.findViewById(R.id.date_announcements);
        textViewTodayDate = itemView.findViewById(R.id.todays_date);

    }
}

【问题讨论】:

  • 请有人帮助我
  • 您不需要两个视图。拥有一个包含所有字段的视图,然后在将数据数组列表发送到 RV 以显示它之前,过滤它并删除您不想显示的元素。这样,您的 recyclerView 将更快地工作,因为在 onBindViewHolder 块中运行的代码将更少。
  • 如何过滤去除不需要的字段?我正在将数据(文件)更新到火力库,然后检索以在 recyclerview 中显示它。每当 Firebase 数据中不存在这两个字段时,Recycler 就不应该显示。
  • 当你从firebase收到数据时,你是放在arraylist还是viewModel中?
  • 在我也删除了这些数据之后,我得到了相同的卡片视图,其中位置和时间字段显示为空。因此,即使我将它们放入 arraylist 并删除不需要的字段。出现同样的问题。

标签: java android firebase google-cloud-firestore


【解决方案1】:

我希望这会有所帮助:

public AnnounceHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View V;

    V = LayoutInflater.from(parent.getContext()).inflate(R.layout.announcements_card_view, parent, false);

    return new AnnounceHolder(V);
}

还有:

protected void onBindViewHolder(@NonNull AnnounceHolder holder, int position, @NonNull Announcements model) {
 holder.textViewTitle.setText(model.getTitle());
 holder.textViewDesc.setText(model.getDescription());
Log.d(TAG, "onBindViewHolder: "+model.getLocation()+" "+model.getDate());
 if (model.getDate()!=null&&model.getLocation()!=null){
     
     //SET THE VIEWS YOU WANNA SEE TO VISIBLE
     holder.YOUR_DATE_FILED.setVisibility(View.VISIBLE);
     holder.YOUR_LOCATION_FILED.setVisibility(View.VISIBLE)

     holder.textViewLocation.setText(model.getLocation());
     holder.textViewDate.setText(model.getDate());

 }
 else{
     //SET THE VIEWS YOU DON'T WANNA SEE TO GONE
     holder.YOUR_DATE_FILED.setVisibility(View.GONE);
     holder.YOUR_LOCATION_FILED.setVisibility(View.GONE)
     
 }

Log.d(TAG, "onBindViewHolder: 2"+flagdateLocation);


String creationDate="";
Date date = model.getTimestamp();
if (date != null) {
    DateFormat dateFormat = SimpleDateFormat.getDateInstance(DateFormat.FULL, Locale.US);
    creationDate = dateFormat.format(date);
    Log.d("TAG", creationDate);
}
 holder.textViewTodayDate.setText(creationDate);

}

【讨论】:

  • 谢谢梅兰☺️。会检查并通知您。
  • 当然。我只是添加了几行。你只需要复制并替换我给你的代码。
  • 当然,梅兰。感谢您的支持。
  • 我刚刚下载了您保存在个人资料中的应用程序。优秀的用户界面。超级先生!我的问题是你花了多少时间来做这件事?
  • 谢谢你的补充,伙计。花了几个月的时间,因为我正在工作,我只是把空闲时间花在这个应用上。
猜你喜欢
  • 2015-01-13
  • 2011-08-25
  • 2011-10-13
  • 2023-04-08
  • 2015-11-12
  • 2012-08-24
  • 2019-03-18
  • 2021-06-24
  • 1970-01-01
相关资源
最近更新 更多