0

I am trying to delete a row when the user clicks on the button to delete. The issue that I am facing is that if I delete any row it removes the last row on UI. I have an adapter with the Arraylist. On click I remove the the item from the arraylist and call notifydatasetchanged . On debugging I am seeing that correct item has been deleted yet on UI I see that last row is not seen (the deleted row can still be seen)

public class MenuDetailsAdapter extends BaseAdapter {
    private Activity activity;
    private LayoutInflater inflater;
    private List<MenuItem> menuItems;
    private View userView,itemView ;
    public MenuDetailsAdapter(Activity activity, List<MenuItem> menuItems) {
        this.activity=activity;
        this.menuItems = menuItems;
    }

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

    @Override
    public Object getItem(int pos) {
        return menuItems.get(pos);
    }

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

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        if (inflater == null) {
            inflater = (LayoutInflater) activity
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }
        if(convertView==null)
        {
            convertView= inflater.inflate(R.layout.menu_card_row, null);
            ImageView im= (ImageView) convertView.findViewById(R.id.btnRemoveItemRow);
            im.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    menuItems.remove(position);
                    notifyDataSetChanged();
                }
            });
            TextView tvItemName=(TextView) convertView.findViewById(R.id.tvItem_name);
            tvItemName.setText(((MenuItem) getItem(position)).getName());

            TextView tvItemPrice=(TextView) convertView.findViewById(R.id.tvItemPrice);
            tvItemPrice.setText(tvItemPrice.getText().toString()+ ((MenuItem) getItem(position)).getCost());

            TextView tvItemQty=(TextView) convertView.findViewById(R.id.tvItem_qty);
            tvItemQty.setText(tvItemQty.getText().toString()+ ((MenuItem) getItem(position)).getQuanity());
        }
        return convertView;
    }
}
Yury Fedorov
  • 14,508
  • 6
  • 50
  • 66
jetty
  • 859
  • 2
  • 17
  • 37
  • @jetty: plz do delete item inside listView.SetOnItemClickListener(). Inside the getView() mth u'll always get position of last row visible inside ListView – kevz Dec 28 '15 at 07:13
  • 1
    Issue is related to `getView ` method use ViewHolder in getView method. see following post [How to implement a view holder?](http://stackoverflow.com/questions/4145602/how-to-implement-a-view-holder) – ρяσѕρєя K Dec 28 '15 at 07:13
  • @jetty ....Check my answer...It can be helpful for you... – Ravindra Kushwaha Dec 28 '15 at 07:22
  • ViewHolder may solve your issue, but also try doing the delete job in your activity using listview.setonItemClickListener(); exactly like @Ajinkya answer :) – Amt87 Dec 28 '15 at 07:24
  • @jetty ... If any solution is working for you....than you should accept or up-vote any one..plz do it... – Ravindra Kushwaha Dec 28 '15 at 14:24

8 Answers8

0
private void deleteRow(int position)
{
menuItems.remove(position);

notifyDataSetChanged();
}
Amit Kumar
  • 547
  • 3
  • 10
0

Change ur getView method as below -

@Override
public View getView(final int position, View convertView, ViewGroup parent) {

    if(convertView == null){
         convertView= inflater.inflate(R.layout.menu_card_row, null);
    }

    ImageView im= (ImageView) convertView.findViewById(R.id.btnRemoveItemRow);
    im.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            menuItems.remove(position);
            notifyDataSetChanged();
        }
    });
    TextView tvItemName=(TextView) convertView.findViewById(R.id.tvItem_name);
    tvItemName.setText(((MenuItem) getItem(position)).getName());

    TextView tvItemPrice=(TextView) convertView.findViewById(R.id.tvItemPrice);
    tvItemPrice.setText(tvItemPrice.getText().toString()+ ((MenuItem) getItem(position)).getCost());

    TextView tvItemQty=(TextView) convertView.findViewById(R.id.tvItem_qty);
    tvItemQty.setText(tvItemQty.getText().toString()+ ((MenuItem) getItem(position)).getQuanity());

return convertView;

}
kevz
  • 2,727
  • 14
  • 39
0

Replace the code with these code....It might be helpful for you

  public class MenuDetailsAdapter extends BaseAdapter {
    private Activity activity;
    private LayoutInflater inflater;
    private List<MenuItem> menuItems;
    private View userView,itemView ;
    public MenuDetailsAdapter(Activity activity, List<MenuItem> menuItems) {
        this.activity=activity;
        this.menuItems = menuItems;
    }

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

    @Override
    public Object getItem(int pos) {
        return menuItems.get(pos);
    }

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

   public class ViewHolder {

    ImageView im;
    TextView tvItemName;
    TextView tvItemPrice;
    TextView tvItemQty;

    }


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


            _viewHolder = new ViewHolder();

            LayoutInflater _layInflater = (LayoutInflater) _context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            convertView = _layInflater.inflate(R.layout.menu_card_row, null);


            _viewHolder.tvItemName=(TextView) convertView.findViewById(R.id.tvItem_name);

            _viewHolder.tvItemPrice=(TextView) convertView.findViewById(R.id.tvItemPrice);
            _viewHolder.tvItemQty=(TextView) convertView.findViewById(R.id.tvItem_qty)



            convertView.setTag(_viewHolder);


        } else {
            _viewHolder = (ViewHolder) convertView.getTag();
        }


            _viewHolder.tvItemName.setText(((MenuItem) getItem(position)).getName());
           _viewHolder.tvItemPrice.setText(tvItemPrice.getText().toString()+ ((MenuItem) getItem(position)).getCost());
          _viewHolder.tvItemQty.setText(tvItemQty.getText().toString()+ ((MenuItem) getItem(position)).getQuanity());

        _viewHolder.im.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    menuItems.remove(position);
                    notifyDataSetChanged();
                }
            })


        return convertView;
    }
Ravindra Kushwaha
  • 7,846
  • 14
  • 53
  • 103
  • i am getiing null pointer exceptions after using the recycler view after i add the second row. I am as of now going with @kevz answer (though it may not be efficient) – jetty Dec 28 '15 at 16:55
  • @jetty .... It ok bro...Whoever you accept the answer..I do not care...my main moto is to help...you rid out from yours problem...is enough for me...all the best....happy coding :) – Ravindra Kushwaha Dec 29 '15 at 04:33
0

You can not remove view directly from here unless your adapter within Activity Class. By using your code, you cannot provide updates to super class constructor.

So you can try this code in your Activity -

listview.setOnItemClickListner(.... use listner


    menuItems.remove(position);
    MenuDetailsAdapter adapter = MenuDetailsAdapter(Activity activity, List<MenuItem> menuItems);
    adapter.notifyDataSetChanged();


);
Ajinkya
  • 1,029
  • 7
  • 15
0

Replace the code with these code....It might be helpful for you. you can change only imageview click listener.

    convertView= inflater.inflate(R.layout.menu_card_row, null);
    ImageView im= (ImageView) convertView.findViewById(R.id.btnRemoveItemRow);
    im.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            menuItems.remove(position);
            notifyDataSetChanged();
        }
    });
    TextView tvItemName=(TextView) convertView.findViewById(R.id.tvItem_name);
    tvItemName.setText(((MenuItem) getItem(position)).getName());

    TextView tvItemPrice=(TextView) convertView.findViewById(R.id.tvItemPrice);
    tvItemPrice.setText(tvItemPrice.getText().toString()+ ((MenuItem) getItem(position)).getCost());

    TextView tvItemQty=(TextView) convertView.findViewById(R.id.tvItem_qty);
    tvItemQty.setText(tvItemQty.getText().toString()+ ((MenuItem) getItem(position)).getQuanity());
Vinit Yadav
  • 284
  • 4
  • 14
0
public class MenuDetailsAdapter extends BaseAdapter {
private Activity activity;
private LayoutInflater inflater;
private List<MenuItem> menuItems;
private View userView,itemView ;
public MenuDetailsAdapter(Activity activity, List<MenuItem> menuItems) {
    this.activity=activity;
    this.menuItems = menuItems;
}

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

@Override
public Object getItem(int pos) {
    return menuItems.get(pos);
}

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

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

    if (inflater == null) {
        inflater = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }
    if(convertView==null)
    {
        convertView= inflater.inflate(R.layout.menu_card_row, null);
        ImageView im= (ImageView) convertView.findViewById(R.id.btnRemoveItemRow);
        im.setOnClickListener(new Listener(position));
        TextView tvItemName=(TextView) convertView.findViewById(R.id.tvItem_name);
        tvItemName.setText(((MenuItem) getItem(position)).getName());

        TextView tvItemPrice=(TextView) convertView.findViewById(R.id.tvItemPrice);
        tvItemPrice.setText(tvItemPrice.getText().toString()+ ((MenuItem) getItem(position)).getCost());

        TextView tvItemQty=(TextView) convertView.findViewById(R.id.tvItem_qty);
        tvItemQty.setText(tvItemQty.getText().toString()+ ((MenuItem) getItem(position)).getQuanity());




    }


    return convertView;
}

 class Listener implements View.OnClickListener {


        private  int position;

        Listener(int  position) {
            this.data = position;

        }

        @Override
        public void onClick(View v) {
                 menuItems.remove(position);
                notifyDataSetChanged();
        }
    }

    }
Rohit Heera
  • 2,709
  • 2
  • 21
  • 31
0

Your ListView works fine, however, it seems you've misunderstood how a ListView in Android works. In Android for saving memory ListViews use a recycling mechanism.

Your logic in getView isn't correct, you're returning every convertViews not being null. Acutally every non-null convertViews are those scrap views which have gone off-screen or have been removed from the model.

In your case, whenever you remove a row, its corresponding view will be marked as scrap and will be taken out of the ListView, So, your ListView will lose one of its rows and now does need another row to cover all of its area. Therefore it asks for another row from the getView method, and there, you're returning the same removed/scrap view which you shouldn't.

Community
  • 1
  • 1
frogatto
  • 28,539
  • 11
  • 83
  • 129
0

use this:

public void deleteRow(int position)
{ 
    menuItems.remove(position);

    adapter.notifyDataSetChanged(); 
}
Sasha O
  • 3,710
  • 2
  • 35
  • 45
  • Can you explain a bit about how/why this works? Explanations are mandatory-ish on SO. – Will Dec 28 '15 at 08:37