3

i want to implement a ListView which have Delete Btn inside of each row.

My only problem is when i click Delete Btn of some Row, Row with Position 0 just Deleted!

i think somehow my Position parameter in getView cannot be updated and always have 0 value

what should i do?!

Thanks.

import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
//import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class InvoiceListAdapter extends BaseAdapter {

  ArrayList<Object> _itemList;
  public Activity _context;
  public LayoutInflater _inflater;


  public InvoiceListAdapter(Activity context,ArrayList<Object> itemList)
  {
      super();
      this._context=context;
      this._itemList=itemList;
      this._inflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

  }
@Override
public int getCount() {
    // TODO Auto-generated method stub
    return _itemList.size();
}

@Override
public Object getItem(int position) {
    // TODO Auto-generated method stub
    return _itemList.get(position);
}

@Override
public long getItemId(int position) {
    // TODO Auto-generated method stub
    return 0;
}

public static class ViewHolder
{
 TextView ProductName;
 TextView Qnt;
 TextView Price;
 Button Del;

}



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

    ViewHolder holder;
     if(convertView==null)
        {
            holder = new ViewHolder();
            convertView = _inflater.inflate(R.layout.custom_row_view, null);


            holder.ProductName = (TextView) convertView.findViewById(R.id.txt_CRow_ProdName);
            holder.Price = (TextView) convertView.findViewById(R.id.txt_CRow_Price);
            holder.Qnt = (TextView) convertView.findViewById(R.id.txt_CRow_Qnt);
            holder.Del = (Button) convertView.findViewById(R.id.btn_CRow_Delete);
            /*-----------------------------Deleting Item with Button--------------------*/
            holder.Del.setTag(holder);
            holder.Del.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(_context,"Item Deleted!", Toast.LENGTH_SHORT).show();

                    _itemList.remove(position);  
                    notifyDataSetChanged();

                    // TODO Auto-generated method stub

                }
            });

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

        AnItem Item = (AnItem) _itemList.get(position);

        holder.ProductName.setText(Item.getProductName());
        holder.Price.setText(Item.getPrice());
        holder.Qnt.setText(Item.getQnt());

        return convertView;


}
Adnan
  • 814
  • 12
  • 38

3 Answers3

11

You are probably having that ListView in ScrollView. I've just wasted 2 hours until I stumbled on this answer:

Why is my BaseAdapter class not incrementing the position in getView?

Community
  • 1
  • 1
nikib3ro
  • 20,366
  • 24
  • 120
  • 181
3
 if(convertView==null)
    {
        holder = new ViewHolder();
        convertView = _inflater.inflate(R.layout.custom_row_view, null);


        holder.ProductName = (TextView) convertView.findViewById(R.id.txt_CRow_ProdName);
        holder.Price = (TextView) convertView.findViewById(R.id.txt_CRow_Price);
        holder.Qnt = (TextView) convertView.findViewById(R.id.txt_CRow_Qnt);
        holder.Del = (Button) convertView.findViewById(R.id.btn_CRow_Delete);
        /*-----------------------------Deleting Item with Button--------------------*/
        holder.Del.setTag(holder);


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

    AnItem Item = (AnItem) _itemList.get(position);

    holder.ProductName.setText(Item.getProductName());
    holder.Price.setText(Item.getPrice());
    holder.Qnt.setText(Item.getQnt());
    holder.Del.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(_context,"Item Deleted!", Toast.LENGTH_SHORT).show();

                _itemList.remove(position);  
                notifyDataSetChanged();

                // TODO Auto-generated method stub

            }
        });

    return convertView;

I think onClickListener is not be inside the if block.

yasinkafadar
  • 229
  • 1
  • 12
  • I think that it isn't good idea. Because objects of type OnClickListener will be created while you scroll. You should setup all listeners in 'if(convertView==null)'. So objects will be created once and reused. – Volodymyr Oct 09 '13 at 12:32
  • Thanks yasinkafadar your code works but for performance are this listener should be inside the if condition? – Adnan Oct 12 '13 at 06:34
  • I think onClickListener is not be inside the if block.-- is moral – Rasel Jul 18 '16 at 06:56
1
@Override
public View getView(final int position, View convertView, ViewGroup parent) {

    ViewHolder holder;
     if(convertView==null)
        {
            holder = new ViewHolder();
            convertView = _inflater.inflate(R.layout.custom_row_view, null);


            holder.ProductName = (TextView) convertView.findViewById(R.id.txt_CRow_ProdName);
            holder.Price = (TextView) convertView.findViewById(R.id.txt_CRow_Price);
            holder.Qnt = (TextView) convertView.findViewById(R.id.txt_CRow_Qnt);
            holder.Del = (Button) convertView.findViewById(R.id.btn_CRow_Delete);
            /*-----------------------------Deleting Item with Button--------------------*/

            holder.Del.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(_context,"Item Deleted!", Toast.LENGTH_SHORT).show();

                    Integer position = (Integer) v.getTag();

                    _itemList.remove(position.intValue());  
                    notifyDataSetChanged();

                    // TODO Auto-generated method stub

                }
            });

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

        AnItem Item = (AnItem) _itemList.get(position);

        holder.ProductName.setText(Item.getProductName());
        holder.Price.setText(Item.getPrice());
        holder.Qnt.setText(Item.getQnt());

        holder.Del.setTag(Integer.valueOf(position));

        return convertView;


}
Volodymyr
  • 1,037
  • 1
  • 11
  • 27
  • i tried you're code and cannot even delete row[0], in my code at least we can delete row[0] but i'm very thankful for your help :) – Adnan Oct 12 '13 at 06:22
  • In my code, you should call notifyDataSetChanged(); after element.remove(pos); – Volodymyr Oct 12 '13 at 06:56
  • Yes Vladimir i used notifyDataSetChanged(); after deletion for updating Adapter but nothing happend. – Adnan Oct 12 '13 at 13:02
  • You know i still don't understand what exactly happens inside and outside the "if" condition. are we just creating objects until fill out the view of List and then updating values inside these object? – Adnan Oct 12 '13 at 13:14