I have an imageButton inside a listview and I want to change its image depending on two cases. In the first case the imagebutton is enabled and has an image. In the second case the imagebutton is disabled and should have a different image.
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.list_row, null);
TextView title = (TextView)vi.findViewById(R.id.title);
TextView retail_price = (TextView)vi.findViewById(R.id.retail_price);
TextView deal_price = (TextView)vi.findViewById(R.id.deal_price);
TextView duration = (TextView)vi.findViewById(R.id.duration);
ImageView thumb_image=(ImageView)vi.findViewById(R.id.list_image);
ImageButton imgb = (ImageButton)vi.findViewById(R.idIMGB);
HashMap<String, String> otherdeals = new HashMap<String, String>();
otherdeals = data.get(position);
title.setText(otherdeals.get(dealsparsing.TAG_TITLE));
retail_price.setText(otherdeals.get(dealsparsing.TAG_RETAIL));
retail_price.setPaintFlags(retail_price.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
deal_price.setText(otherdeals.get(dealsparsing.TAG_DEAL));
duration.setText(otherdeals.get(dealsparsing.TAG_FINAL_TIME));
Bitmap bitmap = DownloadImage(otherdeals.get(dealsparsing.TAG_IMAGE_URL));
thumb_image.setImageBitmap(bitmap);
return vi;
}
You can implement your case logic for imageButton like this.
if(case1)
{
imgb.setImageResource(R.drawable.enableImage);
}
if(case2)
{
imgb.setImageResource(R.drawable.disableImage);
}
You need to define your own (custom) list adapter (if you haven't). In adapter's getView() method you set your button enabled/disbabled and change the image (depending on your case/condition)
Edit: You edited your code and added your adapter's getView method. Now where is the problem? Check your condition and set the ImageButton to enabled/disabled and change the image
Related
I'm creating a custom ListView with multiple elements - TextView and ImageView.
Here's a part of my getView method:
#override
public View getView(int position, View convertView, ViewGroup parent) {
View itemView = convertView;
if (itemView == null) {
itemView = getLayoutInflater().inflate(R.layout.individual_items_in_options, parent, false);
}
// Find the option to start with.
Options currentOption = optionsOfAQuestion.get(position);
// option number
TextView optionNumber = (TextView) itemView.findViewById(R.id.option_number);
optionNumber.setText(currentOption.getOptionNumber());
// option content
TextView optionContent = (TextView) itemView.findViewById(R.id.option_content);
optionContent.setText(currentOption.getOptionContent());
ImageView imageView = (ImageView)findViewById(R.id.option_icon);
imageView.setImageResource(R.drawable.icon_wrong);
I'm getting NPE while setting the image resource, though I've defined it in my layout. Why is setting image giving me NPE, while setting the TextViews work completely fine? What's the point I'm missing here?
replace this
ImageView imageView = (ImageView)findViewById(R.id.option_icon);
by this
ImageView imageView = (ImageView)itemView.findViewById(R.id.option_icon);
this will help you
Please Update your code like below
ImageView imageView = (ImageView) itemView .findViewById(R.id.option_icon);
imageView.setImageResource(R.drawable.icon_wrong);
As Adapter for ListView, I am using custom adapter. On Adapter's getView method, I am trying to change listitem's background image using setBackgroundDrawable.
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
CurrencyModel currency = new CurrencyModel();
currency = currencyList.get(position);
if (convertView == null) {
vi = inflater.inflate(R.layout.listitem_currency, null);
}
TextView tvSymbol = (TextView) vi.findViewById(R.id.tvSymbol);
TextView tvSize = (TextView) vi.findViewById(R.id.tvSize);
TextView tvName = (TextView) vi.findViewById(R.id.tvName);
TextView tvRate = (TextView) vi.findViewById(R.id.tvRate);
tvSymbol.setText(currency.getSymbol());
tvSize.setText(currency.getSize());
tvName.setText(currency.getName());
tvRate.setText(currency.getRate());
if (currency.getSymbol().equals("AUD")) {
vi.setBackgroundDrawable(context.getResources().getDrawable(
R.drawable.bg_exch_high_cell));
}
return vi;
}
When activity starts, everything is working correctly - listitem with AUD has different background. All mystery starts when I scroll the listview - other listitems also get "special" background. The more scroll, the more listitems changed. I do not have idea why this is happening. How to solve this problem?
if (currency.getSymbol().equals("AUD")) {
vi.setBackgroundDrawable(context.getResources().getDrawable(
R.drawable.bg_exch_high_cell));
}
else {//restore default background}
This happens because cell views are reused by listview. You should restore default background for other items.
More about list view performance
TextView tvSymbol = (TextView) vi.findViewById(R.id.tvSymbol);
Before this line add the default background the you put to the item. The reason in your code why it happens is that android try using the the already created view(vi). Since if it is assigned bg_exch_high_cell, it will retain it. So reset it in the beginning.
vi.setBackgroundDrawable(context.getResources().getDrawable(
//default background drawable here ));
TextView tvSymbol = (TextView) vi.findViewById(R.id.tvSymbol);
I have a custom row that contains a text view and 3 Clickable Image Views.
onClick on any one of the ImageView this Image changes to another one.
My problem is that when I click on Image1 on row1, the image changed in both row1 and row9 as well, and when I click on row2, the image changed in row2 and row10 as well.. so On. I don't know why.
But I think it it about scrolling.
This is getView() in my Adapter:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (vi == null) {
vi = inflater.inflate(R.layout.comprow, null);
}
TextView text = (TextView) vi.findViewById(R.id.name);
text.setText(data.get(position));
return vi;
}
And this is OnClick function for the first ImageView
public void one(View v) {
RelativeLayout row = (RelativeLayout)v.getParent();
ImageView im1 = (ImageView) row.findViewById(R.id.one);
ImageView im2 = (ImageView) row.findViewById(R.id.two);
ImageView im3 = (ImageView)row.findViewById(R.id.three);
im1.setImageResource(R.drawable.c0);
im2.setImageResource(R.drawable.b1);
im3.setImageResource(R.drawable.b2);
simpleAdpt.notifyDataSetChanged();
}
When you don't use of id, your changed repeat in all row because you worked with position,then you must set id to each row that create in getView(), now if you have a few choice, you can handle with array of integer with size of list, that in default is equal 0 then if you press one row the value of row changed, then in show image check the value of this row, if is zero then let in default, else check the value and select image that you want to show, I hope that you understand my word
My listview contains one image,and some textview; there are two textiview which contains the price and special price,if special price is 0 than set only price textview and special price let it null,but special price is > 0 than set price value as well special price,fisrt time everything is going good but when i am scrolling the listview then blank textview set with dumyy valueenter code here
Here is my getView method code.
#Override
public View getView(final int position, View convertView, ViewGroup parent){
//public View getView(int position, View convertView, ViewGroup parent) {
/*View vi = convertView;
if (convertView == null)
{
vi = inflater.inflate(R.layout.list_row, null);
}
*/
int pos=position;
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_row, null);
viewHolder=new ViewHolder();
viewHolder.txt_id = (TextView) convertView.findViewById(R.id.id); // title
viewHolder.txt_product_name = (TextView) convertView.findViewById(R.id.title); // title
viewHolder.artist = (TextView) convertView.findViewById(R.id.artist); // artist
// name
viewHolder.txt_mspecialprice_withouttax = (TextView) convertView.findViewById(R.id.duration); // duration
viewHolder.stock = (TextView) convertView.findViewById(R.id.stck);
viewHolder.txt_mprice_withouttax = (TextView) convertView.findViewById(R.id.txtmpricewithouttax);
viewHolder.thumb_image = (ImageView) convertView.findViewById(R.id.list_image); // thumb
// image
convertView.setTag(viewHolder);
}
else{
viewHolder = (ViewHolder) convertView.getTag();
}
HashMap<String, String> song = new HashMap<String, String>();
song = data.get(position);
// Setting all values in listview
String mspecialprice_str=song.get(CustomizedListView.KEY_PRODUCT_MSPECIAL_WITHOUT_TAX);
//String substr_mspecialprice_str=mspecialprice_str.substring(1,mspecialprice_str.indexOf("."));
//String substr_mspecialprice_str_replaced=substr_mspecialprice_str.replace(",", "");
String msaleprice_str=song.get(CustomizedListView.KEY_PRODUCT_MPRICE_WITHOUT_TAX);
//String substr_msaleprice_str=msaleprice_str.substring(0,msaleprice_str.indexOf("."));
//String substr_msaleprice_str_replaced=substr_msaleprice_str.replace(",", "");
viewHolder.txt_id.setText(song.get(CustomizedListView.KEY_PRODUCT_ID));
viewHolder.txt_product_name.setText(song.get(CustomizedListView.KEY_PRODUCT_NAME));
viewHolder.artist.setText(song.get(CustomizedListView.KEY_PRODUCT_DESCRIPTION));
viewHolder.stock.setText(song.get(CustomizedListView.KEY_STOCK));
if(mspecialprice_str.equals("0"))
{
//txt_mspecialprice_withouttax.setText(song.get(CustomizedListView.KEY_PRODUCT_MSPECIAL_WITHOUT_TAX));
viewHolder.txt_mprice_withouttax.setText("$"+(song.get(CustomizedListView.KEY_PRODUCT_MPRICE_WITHOUT_TAX)));
viewHolder.txt_mprice_withouttax.setTextColor(Color.parseColor("#64aef9"));
}
//if(!(mspecialprice_str.equals("0")))
//{
else
{
viewHolder.txt_mspecialprice_withouttax.setText("$"+(song.get(CustomizedListView.KEY_PRODUCT_MSPECIAL_WITHOUT_TAX)));
viewHolder.txt_mprice_withouttax.setText("$"+(song.get(CustomizedListView.KEY_PRODUCT_MPRICE_WITHOUT_TAX)));
viewHolder.txt_mprice_withouttax.setPaintFlags(viewHolder.txt_mprice_withouttax.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
viewHolder.txt_mprice_withouttax.setTextColor(Color.parseColor("#F01616"));
}
imageLoader.DisplayImage(
song.get(CustomizedListView.KEY_PRODUCT_IMAGEURL), viewHolder.thumb_image);
return convertView;
}
}
class ViewHolder {
TextView txt_id ; // title
TextView txt_product_name; // title
TextView artist ; // artist
// name
TextView txt_mspecialprice_withouttax; // duration
TextView stock ;
TextView txt_mprice_withouttax;
ImageView thumb_image ; // thumb
}
ListView, GridView reuse views used as list items/grid elements. getView() is called everytime android tries to draw next element while scrolling your view. There is no need to prevent that!
Edit - Atrix1987
From the developer docs
An Adapter object acts as a bridge between an AdapterView and the underlying data for that view. The Adapter provides access to the data items. The Adapter is also responsible for making a View for each item in the data set.
Suppose you have 10 elements which you want to show using your GridView/ListView and the maximum visible items is 5 then the same 5 views can be reused to display the rest of the 5 elements when you scroll. This is the intended behavior and is the right way to do things [keeps number of views to a minimum].
You don't have control on getView method, the framework does that for you.
The GridView widget extends AdapterView. It uses the adapter to allow the reuse of Views and improve performance. There is no way to avoid calling getView() - it is essential to the whole AdapterView idea. If you want a static layout, perhaps you should use something else.
I have a list. Each row includes an Image at left and two text views on right.
Based on server flag my application opens system media player or open another activity to show news detail.
In my adapter I want to add another image on top my video images (not news images). So, in XML file of Row I have another image View that its visibility is set to "Invisible" and I want to set it to "Visible" for each row which is video.
getView() method is like this:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = myInflater.inflate(R.layout.list_news_adapter, null);
holder = new ViewHolder();
holder.ivIcon = (ImageView) convertView.findViewById(R.id.list_news_icon);
holder.ivPlay = (ImageView) convertView.findViewById(R.id.list_news_PlayIcon);
holder.tvTitle = (TextView) convertView.findViewById(R.id.list_news_title);
holder.tvDate = (TextView) convertView.findViewById(R.id.list_news_date);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.tvTitle.setText(mLatestNews.getTitle().get(position));
holder.tvDate.setText(localTime.get(position));
if(mLatestNews.getType().get(position).equalsIgnoreCase("VIDEO"))
holder.ivPlay.setVisibility(View.VISIBLE);
// Load and display image
String imageUrl = (mLatestNews.getImageLink().get(position));
imageUrl = imageUrl.trim().replaceAll(" ", "%20");
imageLoader.displayImage(imageUrl, holder.ivIcon, options);
return convertView;
}
static class ViewHolder {
ImageView ivIcon;
ImageView ivPlay;
TextView tvTitle;
TextView tvDate;
}
Normally first four items of list are video and rest are news. When I run the appllication, not only 4 first items, even second image will be activated (set to visible) for some news items.
correct result is like this image:
but after scroll of list, second image (white triangle) adds to news items. like this image:
I have no idea why it happens. any suggestion would be appreciated.
Oh, my god!!!!
It just needs "else". I changed the code like this:
if(mLatestNews.getType().get(position).equalsIgnoreCase("VIDEO"))
holder.ivPlay.setVisibility(View.VISIBLE);
else
holder.ivPlay.setVisibility(View.INVISIBLE);
Now, it's working.