Search code examples
androidandroid-listviewandroid-arrayadapternotifydatasetchanged

Cant update data from within a ArrayAdapter


Im using a array adapter with a so show a list of linear layouts. The layouts have 3 text fields and a hidden button that is shown when the list item is clicked. What I am trying to do is attach a onclicklistener to the button that will delete that row from the arraylist/adapter and update the data set. I have the following code:

public class CheckAdapter extends ArrayAdapter<Check> {
    Context context;
    int layoutResourceId;
    ArrayList<Check> data = null;

    public CheckAdapter(Context context, int resource, ArrayList<Check> objects) {
        super(context, resource, objects);
        this.context = context;
        this.layoutResourceId = resource;
        this.data = objects;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;

        if(convertView == null){
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            convertView = inflater.inflate(layoutResourceId, parent, false);

            holder = new ViewHolder(convertView.findViewById(R.id.checklistRoot));
            holder.checkName = (TextView) convertView.findViewById(R.id.checklistname);
            holder.checkNumber = (TextView) convertView.findViewById(R.id.checklistnumber);
            holder.checkTotal = (TextView) convertView.findViewById(R.id.checklisttotal);
            holder.deleteButton = (Button) convertView.findViewById(R.id.deletecheck);

            holder.swipeButtons();

            convertView.setTag(holder);
        }
        else
        {
            holder = (ViewHolder)convertView.getTag();
            holder.swipeButtons();
        }

        String name = data.get(position).getName();
        Double total = data.get(position).getAmmount();
        Long number = data.get(position).getCheckNumber();

        holder.checkName.setText(name);
        holder.checkNumber.setText(number.toString());
        holder.checkTotal.setText(total.toString());

        holder.deleteButton.setTag(position);
        holder.deleteButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Integer position = (Integer) view.getTag();
                Log.d("Check Adapter", "Button Clicked: " + position);
                data.remove(position);
                notifyDataSetChanged();
            }
        });
        return convertView;

    }

    static class ViewHolder{
        TextView checkName;
        TextView checkNumber;
        TextView checkTotal;
        Button deleteButton;
        View rootView;


        ViewHolder(View rootView) {
            this.rootView = rootView;
        }

        public void swipeButtons(){
            rootView.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent motionEvent) {
                    deleteButton.setVisibility(View.VISIBLE);
                    return false;
                }
            });
        }
    }
}

My logs are showing I have the correct position being sent into data.remove(position); However the ListView doesn't seem to be updating and the data seems to be remaining. Any suggestions?

Thanks so much!


Solution

  • You can also try using position value provided by getView method itself. Also remove line holder.deleteButton.setTag(position); from getView method.

    so your code will be like below :

    @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
    
            // --- Your other code ---//
    
    
            holder.deleteButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    data.remove(position);
                    notifyDataSetChanged();
                }
            });
            return convertView;
    
        }
    

    Hope this will help you.