Android - 隐藏自定义适配器中的列表项在 .setText 崩溃

Android - Hiding List Items in a Custom Adapter crashing at .setText

我正在尝试使用我的自定义列表适配器从我的列表中隐藏列表项。我可以让列表项隐藏,但是当我尝试滚动列表时,我会出现以下错误:

 java.lang.NullPointerException: 
 Attempt to read from field 'android.widget.TextView com.example.QuestionListAdapter$ViewHolder.tvqid'
 on a null object reference
 at com.example.QuestionListAdapter.getView(QuestionListAdapter.java:196)

这是我的 getView 代码:

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    View rowView = convertView;
    Questions questionListItems = contactList.get(position);
    hidden = questionListItems.getHidden();

    if (rowView == null) {
        if (hidden.equals("true")){
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            rowView = inflater.inflate(R.layout.null_item, null);
            return rowView;
        } else {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            rowView = inflater.inflate(R.layout.activity_question_view_row, null);
            ViewHolder viewHolder = new ViewHolder();
            viewHolder.tvqname = (TextView) rowView.findViewById(R.id.name);
            viewHolder.tvqid = (TextView) rowView.findViewById(R.id.qid);
            rowView.setTag(viewHolder);
        }
    }

    final ViewHolder holder = (ViewHolder) rowView.getTag();
    holder.tvqid.setText(qid); //ERROR IS HERE
    holder.tvqname.setText(qname);
return rowview;     
} 

错误出现在 .setText 上,因为它试图设置空项的文本。但我已经尝试将我的 hidden.equals("true") 检查放在 .setText 上,但它仍然使应用程序崩溃。

我也试过使用下面的代码代替上面的代码,下面的代码删除了列表项并使列表可滚动。但是它在那些列表项所在的位置留下了白色 space。

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    View rowView = convertView;
    Questions questionListItems = contactList.get(position);
    hidden = questionListItems.getHidden();

    if (rowView == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            rowView = inflater.inflate(R.layout.activity_question_view_row, null);
            ViewHolder viewHolder = new ViewHolder();
            viewHolder.tvqname = (TextView) rowView.findViewById(R.id.name);
            viewHolder.tvqid = (TextView) rowView.findViewById(R.id.qid);
            rowView.setTag(viewHolder);
    }

    final ViewHolder holder = (ViewHolder) rowView.getTag();
    holder.tvqid.setText(qid); //ERROR IS HERE
    holder.tvqname.setText(qname);

   if (hidden.equals("true")){
        rowView.setVisibility(View.GONE);
    } else {
        rowView.setVisibility(View.VISIBLE);

    }
  return rowview;     
} 

此外,在上面的第二个代码片段中。我尝试使用 rowView = new Space(this) 而不是将可见性设置为 GONE,但滚动时应用程序崩溃了。

我认为您应该使用提供给适配器的数组而不是适配器的视图。 基本上要隐藏一个元素,您需要将其从适配器的数组中删除。没有什么能阻止您在其他地方(或适配器本身)保留完整数组的副本。

例如,当你想更新你的 ListView 时,你可以在你的适配器之外,在片段 / activity 中执行以下操作,在那里你将你的 ArrayList of Questions 提供给它:

ArrayList<Questions> questionListItemsInAdapter = new ArrayList<>();

for(Questions questions:questionListItems)
   if(!questions.getHidden())
      questionListItemsInAdapter.add(questions);

adapter.bind(questionListItemsInAdapter);
adapter.notifyDataSetChanged();