0

I have a custom adapter extended from a base one, and I got a spinner inside each row (something related to quantity for each product -> item from listview). When user selects a different value of the spinner, I have to refresh a TextView which shows the total price (TextView from that row -- productQuantity * productPrice ). Problem is, calling for notifyDataSetChanged in spinner.setOnItemClickListener totally messes my listview, lowering the frames a lot. Are there any (other maybe) solution to solve this problem.. (I was looking for refreshing one row inside adapter getView, but couldn't find a suitable solution).

Adapter

public class CartAdapter extends BaseAdapter {

private List<ProductDetailedHolder> itemsList = new ArrayList<ProductDetailedHolder>();
private ProductDetailedHolder item = null;
private Activity activity;
private final String[] quantityValues = new String[] { "1", "2", "3", "4",
        "5", "6", "7", "8", "9", "10" };
private DisplayImageOptions options = new DisplayImageOptions.Builder()
        .showImageOnFail(R.drawable.bulina)
        .displayer(new RoundedBitmapDisplayer(15))
        .bitmapConfig(Bitmap.Config.RGB_565)
        .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2).build();

private ViewHolder holder = null;
private ImageLoader imageLoader;

public CartAdapter(List<ProductDetailedHolder> array, Activity activity,
        ImageLoader imageLoader) {
    this.activity = activity;
    this.itemsList = array;
    this.imageLoader = imageLoader;

}

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

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

@Override
public long getItemId(int position) {
    return itemsList.get(position).getProductId();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    item = itemsList.get(position);

    if (convertView == null) {
        convertView = activity.getLayoutInflater().inflate(
                R.layout.row_cart_item, null);

        holder = new ViewHolder(convertView);

        ArrayAdapter<String> quantityAdapter = new ArrayAdapter<String>(
                activity, android.R.layout.simple_spinner_item,
                quantityValues);

        quantityAdapter
                .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        holder.spin_row_cart_quantity.setAdapter(quantityAdapter);

        holder.spin_row_cart_quantity
                .setOnItemSelectedListener(new OnItemSelectedListener() {

                    @Override
                    public void onItemSelected(AdapterView<?> arg0,
                            View arg1, int arg2, long arg3) {

                        int getPosition = (Integer) arg0.getTag();

                        Log.d(ServiceManager.TagOSDShop, "getPosition: "
                                + getPosition);

                        itemsList.get(getPosition).setProductQuantity(
                                Integer.valueOf(
                                        arg0.getSelectedItem().toString())
                                        .intValue());

// here I need to refresh the row with holder.tv_row_cart_price.setText ( productQuantity * productPrice), but I can't use notifyDataSetChanged on all adapter, because this would refresh the entire list (and spinner.setOnItemSelected fires when the list is initialised, causing my listview to run very slow and ugly.



                    }

                    @Override
                    public void onNothingSelected(AdapterView<?> arg0) {
                        // do nothing
                    }
                });

        holder.ib_row_cart_delete
                .setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {

                        int getPosition = (Integer) v.getTag();
                        itemsList.remove(getPosition);

                    }
                });

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

    holder.tv_row_cart_title.setText(item.getProductName());

    holder.tv_row_cart_color.setText(Html
            .fromHtml("<font color=\"#999999\"> Color </font> <br />"
                    + item.getProductColor()));
    holder.tv_row_cart_size.setText(Html
            .fromHtml("<font color=\"#999999\"> Size </font> <br />"
                    + item.getProductSize()));
    holder.tv_row_cart_details.setText(item.getProductDescription());
    holder.tv_row_cart_price.setText(String.valueOf(item.getProductPrice()
            * item.getProductQuantity()));

    holder.ib_row_cart_delete.setTag(position);

    holder.spin_row_cart_quantity.setSelection(findSelection(item));

    holder.spin_row_cart_quantity.setTag(position);

    imageLoader.displayImage(item.getProductImageUrl(),
            holder.iv_row_cart_content, options);

    return convertView;
}

private int findSelection(ProductDetailedHolder item) {

    for (int i = 0; i < quantityValues.length; i++) {
        if (Integer.valueOf(quantityValues[i]).intValue() == item
                .getProductQuantity()) {
            return i;
        }
    }

    Log.e(ServiceManager.TagOSDShop,
            "findSelection returned invalid position!!!");
    return -1;
}

static class ViewHolder {

    public TextView tv_row_cart_title;
    public TextView tv_row_cart_color;
    public TextView tv_row_cart_size;
    public TextView tv_row_cart_price;
    public TextView tv_row_cart_details;
    public ImageButton ib_row_cart_delete;
    public ImageView iv_row_cart_content;
    public Spinner spin_row_cart_quantity;

    public ViewHolder(View convertView) {

        tv_row_cart_title = (TextView) convertView
                .findViewById(R.id.tv_row_cart_title);
        tv_row_cart_color = (TextView) convertView
                .findViewById(R.id.tv_row_cart_color);
        tv_row_cart_size = (TextView) convertView
                .findViewById(R.id.tv_row_cart_size);
        tv_row_cart_price = (TextView) convertView
                .findViewById(R.id.tv_row_cart_price);
        tv_row_cart_details = (TextView) convertView
                .findViewById(R.id.tv_row_cart_details);
        ib_row_cart_delete = (ImageButton) convertView
                .findViewById(R.id.ib_row_cart_delete);
        iv_row_cart_content = (ImageView) convertView
                .findViewById(R.id.iv_row_cart_content);
        spin_row_cart_quantity = (Spinner) convertView
                .findViewById(R.id.spin_row_cart_quantity);

    }

}

btw, my spinner has some constant values, like 1,2,.. 20.

DoruAdryan
  • 1,314
  • 3
  • 20
  • 35
  • have you tried `View v = ListView.getChildAt(position);` – Naveen Apr 26 '13 at 09:44
  • How should I get "**ListView**" inside adapter's getView ? – DoruAdryan Apr 26 '13 at 11:24
  • no not inside the getView. You can use this method any where outside the adapter. Replace ListView with your listview name – Naveen Apr 29 '13 at 02:51
  • you will need to create a listener in your adapter and then implement it in your activity, then from your activity you can call the getChildAt method and refresh the view. – Naveen Apr 29 '13 at 03:16
  • check http://stackoverflow.com/questions/3724874/how-can-i-update-a-single-row-in-a-listview – Naveen Apr 29 '13 at 03:20
  • this is indeed what I was looking for, but I have some trouble creating the listener in my adapter that should be used in activity, as I am not really very familiar to it (should it be an interface, whose callback should be used in my activity inside updateSingleView private method?). If you could help me out with this please, and btw, write down your answer so I can accept it. – DoruAdryan Apr 29 '13 at 07:14
  • you are correct, you will need interface for listener. I have added my comments as answer. If you need any help in code let me know. – Naveen Apr 29 '13 at 08:05

2 Answers2

0

Refer this link.
It may be helpful for you

jimpanzer
  • 3,470
  • 4
  • 44
  • 84
Piyush
  • 3,061
  • 8
  • 34
  • 52
  • same comment as for Kenn Peterson, I just need to solve the "_refreshing puzzle_" no need to show how to use a Spinner – DoruAdryan Apr 26 '13 at 11:25
0

You will need to create a listener in your adapter and then implement it in your activity, then from your activity you can call the listview.getChildAt(position) method and refresh the view as you like.

You can implement the listener using interface and you activity will need to implement the interface.

Naveen
  • 1,703
  • 13
  • 22