Reputation: 94
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
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
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