Matic Tuma
Matic Tuma

Reputation: 94

ImageViews in ListViews

I have a question about ImageViews in a ListView.

I made a ListView and in every row I have 2 TextViews (tvName and tvPrice), I get values for TextViews from my DB, and an ImageView (ivAvailability) that shows if the item is available (green circle - available, red circle - unavailable) and images in use are stored in the res/drawable folder. I have also implemented GCM service and I am using it to update the ImageViews when the availability of an item changes.

Example: I have 3 items in my ListView (item1, item2, item3). We find out that we ran out of item3 so we want to update the picture from green circle to the red one. In my GCM message I have a int value (0 if not available and 1 if available) and I want the ImageView to change accordingly.

In my ListActivity I receive the GCM message with a BroadcastReceiver

private BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String item = intent.getStringExtra("item");
        int id = intent.getIntExtra("id", 0); // 0 => id's default value
        int available = intent.getIntExtra("available", 0); // 0 => availability's default value

        Log.d(TAG, "Item: " + item);
        Log.d(TAG, "ID: " + id);
        Log.d(TAG, "Availability: " + availability);

        updateView(id, availability);

        adapter.notifyDataSetChanged();
    }
};

And here is my updateView method

private void updateView(int id, int availability){
    View v = lvItem.getChildAt(id);
    if(v == null) return;

    switch (availability){
        case 0:
            //here i want to call the imageView in the respected row (example in row 3) and
            //change it with something like `setImageResource(R.drawable.traffic_red);`
            break;
        case 1:
            //here i want to call the imageView in the respected row (example in row 3) and
            //change it with something like `setImageResource(R.drawable.traffic_green);`
            break;
    }

}

My GenericViewHolder.java

public class GenericViewHolder {
    public View root;
    public TextView[] stringFields;
    public ImageView[] staticImageFields;
    public View[] baseFields;
}

My getView() method

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

    // Inflate a new view or use a recycled view.
    View v = convertView;
    GenericViewHolder holder;

    if (null == v) {
        LayoutInflater vi =
                (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(mLayoutResource, null);
        holder = new GenericViewHolder();
        holder.root = v;
        // init the sub views and put them in a holder instance
        CustomAdapterUtils.initViews(v, holder, mBindDictionary);

        v.setTag(holder);
    } else {
        holder = (GenericViewHolder) v.getTag();
    }

    // Show the data
    final T item = getItem(position);
    showData(item, holder, position);

    return v;
}

And the xml file of an Item

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:id="@+id/tvName"
    android:layout_alignParentTop="true"
    android:layout_alignParentStart="true"
    android:text="Large Text" />

 <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:text="Large Text"
    android:id="@+id/tvPrice"
    android:layout_below="@+id/tvName"
    android:layout_alignParentStart="true" />

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/ivTrafficLight"
    android:contentDescription=""
    android:layout_alignParentTop="true"
    android:layout_alignParentEnd="true"
    android:src="@mipmap/ic_launcher" />

I am using this (FunDapter) lib.

So my question is how can I find the ImageView in the 3rd row? I tried findViewById(R.id.ivAvailability) but this always changes the ImageView in the top row not the one I would want to. So how do i distinct them from oneanother?

Upvotes: 0

Views: 82

Answers (2)

Goltsev Eugene
Goltsev Eugene

Reputation: 3637

Ok, I didn't see code of your Adapter, but anyway it's a good idea to use ViewHolder inner class in Adapters.

public static class ViewHolder {
    public ImageView imageView;
}

Then, in your getView method you can do something like that:

    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder _viewHolder;
        if(convertView == null) {
            convertView = _layLayoutInflater.inflate(_resourceID, parent, false);
            _viewHolder = new ViewHolder();
            _viewHolder.imageView = (ImageView) convertView.findViewById(R.id.item_image);

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

        return convertView;
    }

After all, when you do View v = lvItem.getChildAt(id); make following:

Adapter.ViewHolder viewHolder = (Adapter.ViewHolder) v.getTag();
viewHolder.imageView.setImageResource(...)

Try, hope it helps.


Update. Ok, both of this is working for me.
1.

YourAdapter.GenericViewHolder vh = (YourAdapter.GenericViewHolder) v.getTag();
vh.someTextField.setText("bbbbb");

2.

TextView t = (TextView) v.findViewById(R.id.your_item);
t.setText("abracadabra");

Please try firstly with text boxes, then with image containers. Thanks.
PS. Both worked without calling notifyDataSetChanged().

Upvotes: 2

Raghu Nagaraju
Raghu Nagaraju

Reputation: 3288

View v = lvItem.getChildAt(id); this will return you the particular row item.

You can get the imageview on the row item as below

v.findViewById(R.id.ivAvailability);

Upvotes: 0

Related Questions