Search code examples
androidlistviewbaseadapternotifydatasetchanged

notifyDatasetChanged is not working inside the getView() method for Custom Adapter In Android


I am basically trying hide and show a text in the list row when I am clicking a button in the list row. I have added the onClick() for the button inside getView() method and then calling the notifyDataSetChanged(). But it is not working. No change in the text visibility. Here is my custom Adapter code:

  public class ListAdapter extends BaseAdapter {
    private Context context;
    private List<String> mListQuestion = null;
    private List<String> mListAnswer = null;
    ViewHolder holder = null;
    boolean flag = false;

    public ListAdapter(Context context, List<String> question, List<String> answer ) {
        this.mListQuestion = question;
        this.mListAnswer = answer;
        this.context = context;
    }

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

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

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

    @Override
    @SuppressWarnings("deprecation")
    public View getView(int position, View convertView, ViewGroup parent) {


        if (convertView == null)
        {
            LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = vi.inflate(R.layout.list_faq_item, null);

            holder = new ViewHolder();
            holder.tvQuestion = (TextView) convertView.findViewById(R.id.text);
            holder.tvAns = (TextView) convertView.findViewById(R.id.anstext);
            holder.ivArrow = (Button)convertView.findViewById(R.id.arrow_expand);
            convertView.setTag(holder);
        }
        else
        {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.tvQuestion.setText(mListQuestion.get(position));
        holder.tvAns.setText(mListAnswer.get(position));
        holder.ivArrow.setOnClickListener(new View.OnClickListener()
        {
                @Override
                public void onClick(View v)
                {
                    if (flag == false)
                    {
                        Logger.d("arrow clicked when flag is false");
                        holder.tvAns.setVisibility(View.VISIBLE);
                        holder.ivArrow.setBackgroundResource(R.drawable.up_arrow);
                        flag = true;
                    }
                    else if (flag == true)
                    {
                        Logger.d("arrow clicked when flag is true");
                        holder.tvAns.setVisibility(View.GONE);
                        holder.ivArrow.setBackgroundResource(R.drawable.down_arrow);
                        flag = false;
                    }
                    notifyDataSetChanged();
                }
        });

        return convertView;
    }


    static class ViewHolder {
        TextView tvQuestion;
        TextView tvAns;
        Button ivArrow;
    }

}

Can someone please tell what I am doing wrong here. Thanks in Advance.

-Arindam.


Solution

  • public class ListAdapter extends BaseAdapter {
        private Context context;
        private List<String> mListQuestion = null;
        private List<String> mListAnswer = null;
        ViewHolder holder = null;
        private List<Boolean> textViewVisibileState; 
    
        public ListAdapter(Context context, List<String> question, List<String> answer ) {
            this.mListQuestion = question;
            this.mListAnswer = answer;
            this.context = context;
            this.textViewVisibileState=new ArrayList<>(Arrays.asList(new Boolean[getCount()]));
              Collections.fill(this.textViewVisibileState,false);
        } 
    
        @Override 
        public Object getItem(int position)
        { 
            return mListQuestion.get(position);
        } 
    
        @Override 
        public long getItemId(int position) {
            return position;
        } 
    
        @Override 
        public int getCount() { 
            return mListQuestion.size();
        } 
    
        @Override 
        @SuppressWarnings("deprecation") 
        public View getView(int position, View convertView, ViewGroup parent) {
    
    
            if (convertView == null)
            { 
                LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = vi.inflate(R.layout.list_faq_item, null);
    
                holder = new ViewHolder();
                holder.tvQuestion = (TextView) convertView.findViewById(R.id.text);
                holder.tvAns = (TextView) convertView.findViewById(R.id.anstext);
                holder.ivArrow = (Button)convertView.findViewById(R.id.arrow_expand);
                convertView.setTag(holder);
            } 
            else 
            { 
                holder = (ViewHolder) convertView.getTag();
            } 
    
            holder.tvQuestion.setText(mListQuestion.get(position));
            holder.tvAns.setText(mListAnswer.get(position));
            if(textViewVisibileState.get(position))
    {
                holder.tvAns.setVisibility(View.GONE);
                            holder.ivArrow.setBackgroundResource(R.drawable.down_arrow);
    
    }
    else
    {
        Logger.d("arrow clicked when flag is false"); 
                            holder.tvAns.setVisibility(View.VISIBLE);
                            holder.ivArrow.setBackgroundResource(R.drawable.up_arrow);
    
    }
            holder.ivArrow.setOnClickListener(new View.OnClickListener()
            { 
                    @Override 
                    public void onClick(View v)
                    { 
                        if (textViewVisibileState.get(position))
                        { 
                            textViewVisibileState.set(position,false);
       } 
                        else
                        { 
    
                            textViewVisibileState.set(position,true);
    
     } 
                        notifyDataSetChanged();
                    } 
            }); 
    
            return convertView;
        } 
    
    
        static class ViewHolder { 
            TextView tvQuestion;
            TextView tvAns;
            Button ivArrow;
        } 
    
    } 
    

    This will work.