Search code examples
androidbaseadapter

boolean variable unavailable in getView()


I never understand the getView() method fully. Here is a case:

enter image description here

Here I have isNoticeRead which is false you can see. But the line gets executed! And when the line in the if statement is executing, isNoticeRead is not found anywhere! If I even place my cursor over it, nothing happens (no tooltip). And it happens for the first item of the ListView. Can you please tell me what am I missing?

My full Adapter

public class NoticesListViewAdapter extends BaseAdapter{

    Context context;
    ArrayList<NoticeModel> items;
    String[] readNotices;

    public NoticesListViewAdapter(Context context, ArrayList<NoticeModel> items) {
        this.context                                    = context;
        this.items                                      = items;
        readNotices                                     = SharedPrefUtils.getMarkedNotices(context).split(SharedPrefUtils.SEPARATOR_READ_NOTICE);
    }

    @Override
    public int getCount() {
        return items.size();
    }

    @Override
    public Object getItem(int position) {
        return items.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Holder holder;
        if(convertView == null){
            convertView                                 = LayoutInflater.from(context).inflate(R.layout.list_item_notices, null);
            holder                                      = new Holder();
            holder.noticeID                             = (TextView) convertView.findViewById(R.id.noticeID);
            holder.tvNotice                             = (TextView) convertView.findViewById(R.id.tvNotice);
            holder.tvDateTime                           = (TextView) convertView.findViewById(R.id.tvDateTime);
            holder.tvNoticeRead                         = (TextView) convertView.findViewById(R.id.tvNoticeRead);
            convertView.setTag(holder);
        }else{
            holder                                      = (Holder) convertView.getTag();
        }
        try {
            String str = items.get(position).getId() + "";
            holder.noticeID.setText(str);
            holder.tvNotice.setText(items.get(position).getText());
            holder.tvDateTime.setText(DateTimeUtils.changeDateTimeFormat(items.get(position).getDateTime(), DateTimeUtils.FORMAT8, DateTimeUtils.FORMAT3));

            final boolean isNoticeRead = items.get(position).isRead();
            if (isNoticeRead) {
                holder.tvNoticeRead.setVisibility(View.VISIBLE);
            }

        //        for(String s : readNotices) {
        //            if (s.equals(str)) {
        //                holder.tvNoticeRead.setVisibility(View.VISIBLE);
        ////                break;
        //            }
        //        }
        }catch (Exception e){e.printStackTrace();}

        return convertView;
    }

    class Holder{
        TextView tvNotice, tvDateTime, noticeID, tvNoticeRead;
    }
}

Solution

  • The views of your holder are being re-used by the List. Thus you may have an instance which is initialized with VISIBLE, but when the view is reused and filled, you don't reset its state - so it is still visible.

    if (isNoticeRead) {
        holder.tvNoticeRead.setVisibility(View.VISIBLE);
    } else {
        holder.tvNoticeRead.setVisibility(View.INVISIBLE);
    }