Android Problems with onClickListener in Adapter - android

I've spent hours searching for a solution but everything I've tried doesn't work, it simply yields the same results as the code below does.
I am trying to have an onClickListener change the visibility of a TextView but this code always sets the one I click and then another one below.
class EventiAdapter extends ArrayAdapter<CustomEventi> {
List<CustomEventi> customEventi;
LayoutInflater inflater;
EventiAdapter(#NonNull Context context, #LayoutRes int resource, List<CustomEventi> objects) {
super(context, resource, objects);
customEventi = objects;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#NonNull
#Override
public View getView(final int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View view = convertView;
final EventiViewHolder eventiViewHolder;
if(view == null) {
eventiViewHolder = new EventiViewHolder();
view = inflater.inflate(R.layout.eventi_list, parent, false);
eventiViewHolder.imageTV = (ImageView) view.findViewById(R.id.image);
eventiViewHolder.nameTV = (TextView) view.findViewById(R.id.name);
eventiViewHolder.categoryTV = (TextView) view.findViewById(R.id.category);
eventiViewHolder.latLngTV = (TextView) view.findViewById(R.id.latLng);
eventiViewHolder.placeTV = (TextView) view.findViewById(R.id.place);
eventiViewHolder.dateTV = (TextView) view.findViewById(R.id.date);
eventiViewHolder.timeTV = (TextView) view.findViewById(R.id.time);;
eventiViewHolder.viewInfo = (Button) view.findViewById(R.id.viewInfo);
eventiViewHolder.informationTV = (TextView) view.findViewById(R.id.information);
eventiViewHolder.mapImage = (ImageView) view.findViewById(R.id.mapImage);
view.setTag(eventiViewHolder);
} else {
eventiViewHolder = (EventiViewHolder) view.getTag();
}
eventiViewHolder.viewInfo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(eventiViewHolder.informationTV.getVisibility() == View.VISIBLE) {
eventiViewHolder.informationTV.setVisibility(View.GONE);
eventiViewHolder.mapImage.setVisibility(View.GONE);
eventiViewHolder.viewInfo.setText("VISUALIZZA INFORMAZIONI");
}
else {
eventiViewHolder.informationTV.setVisibility(View.VISIBLE);
eventiViewHolder.mapImage.setVisibility(View.VISIBLE);
eventiViewHolder.viewInfo.setText("NASCONDI INFORMAZIONI");
}
}
});
System.out.println("POSITION: "+position);
CustomEventi cstEventi = customEventi.get(position);
eventiViewHolder.setDataIntoViewHolder(cstEventi);
return view;
}
}
Thank you in advance to anyone who'll try to help me.

Try
1. Add a boolean field visible to CustomEventi class
private boolean visible;
public boolean isVisible { return visible; }
public void setVisible(boolean visible) { this.visible = visible; }
2. Replace your adapter code with this one:
class EventiAdapter extends ArrayAdapter<CustomEventi> {
List<CustomEventi> customEventi;
LayoutInflater inflater;
EventiAdapter(#NonNull Context context, #LayoutRes int resource, List<CustomEventi> objects) {
super(context, resource, objects);
customEventi = objects;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#NonNull
#Override
public View getView(final int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View view = convertView;
final EventiViewHolder eventiViewHolder;
System.out.println("POSITION: "+position);
CustomEventi cstEventi = customEventi.get(position);
if(view == null) {
eventiViewHolder = new EventiViewHolder();
view = inflater.inflate(R.layout.eventi_list, parent, false);
eventiViewHolder.imageTV = (ImageView) view.findViewById(R.id.image);
eventiViewHolder.nameTV = (TextView) view.findViewById(R.id.name);
eventiViewHolder.categoryTV = (TextView) view.findViewById(R.id.category);
eventiViewHolder.latLngTV = (TextView) view.findViewById(R.id.latLng);
eventiViewHolder.placeTV = (TextView) view.findViewById(R.id.place);
eventiViewHolder.dateTV = (TextView) view.findViewById(R.id.date);
eventiViewHolder.timeTV = (TextView) view.findViewById(R.id.time);;
eventiViewHolder.viewInfo = (Button) view.findViewById(R.id.viewInfo);
eventiViewHolder.informationTV = (TextView) view.findViewById(R.id.information);
eventiViewHolder.mapImage = (ImageView) view.findViewById(R.id.mapImage);
view.setTag(eventiViewHolder);
} else {
eventiViewHolder = (EventiViewHolder) view.getTag();
}
eventiViewHolder.informationTV.setVisibility(cstEventi.isVisible() ? View.VISIBLE : GONE);
eventiViewHolder.mapImage.setVisibility(cstEventi.isVisible() ? View.VISIBLE : View.GONE);
eventiViewHolder.viewInfo.setText(cstEventi.isVisible() ? "NASCONDI INFORMAZIONI": "VISUALIZZA INFORMAZIONI");
eventiViewHolder.viewInfo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
boolean isVisible = customEventi.isVisible();
customEventi.setVisible(!isVisible);
notifyDataSetChanged();
}
});
eventiViewHolder.setDataIntoViewHolder(cstEventi);
return view;
}
}

Try this one....
public View getView(final int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View view = convertView;
if(view == null) {
view = inflater.inflate(R.layout.eventi_list, parent,false);
imageTV = (ImageView) view.findViewById(R.id.image);
nameTV = (TextView) view.findViewById(R.id.name);
categoryTV = (TextView) view.findViewById(R.id.category);
latLngTV = (TextView) view.findViewById(R.id.latLng);
placeTV = (TextView) view.findViewById(R.id.place);
dateTV = (TextView) view.findViewById(R.id.date);
timeTV = (TextView) view.findViewById(R.id.time);;
viewInfo = (Button) view.findViewById(R.id.viewInfo);
informationTV = (TextView) view.findViewById(R.id.information);
mapImage = (ImageView) view.findViewById(R.id.mapImage);
viewInfo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(informationTV.getVisibility() == View.VISIBLE) {
informationTV.setVisibility(View.GONE);
mapImage.setVisibility(View.GONE);
viewInfo.setText("VISUALIZZA INFORMAZIONI");
}
else {
informationTV.setVisibility(View.VISIBLE);
mapImage.setVisibility(View.VISIBLE);
viewInfo.setText("NASCONDI INFORMAZIONI");
}
}
});
System.out.println("POSITION: "+position);
CustomEventi cstEventi = customEventi.get(position);
setDataIntoViewHolder(cstEventi);
return view;
}

Related

Confusion with getview android imagebuttons

I have a listview which has two image buttons in the row. Tapping image button change the background color. When I tap on the first list item, image button background change and the view is saved but scrolling bottom of the listview, background color of image button of another list item changes as well. Below is the getView of Custom Adapter. How can I avoid this problem?
public View getView(final int i, View view, ViewGroup viewGroup) {
ViewHolder holder = new ViewHolder();
holder = null;
//view=null;
if (inflater == null) {
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
if (view == null) {
view = inflater.inflate(R.layout.student_list, null);
holder = new ViewHolder();
holder.presentButton = (ImageButton) view.findViewById(R.id.imageView);
holder.absentButton = (ImageButton) view.findViewById(R.id.imageView2);
holder.presentButton.setBackgroundColor(0);
holder.absentButton.setBackgroundColor(0);
view.setTag(holder);
}
else {
holder = (ViewHolder) view.getTag();
}
final SQLiteStudents db1 = new SQLiteStudents(activity.getApplicationContext());
final TextView tvName = (TextView) view.findViewById(R.id.tv_name);
final TextView tvRoll = (TextView) view.findViewById(R.id.tv_roll);
final studentInfo s = students.get(i);
tvRoll.setText(s.getRoll() + ".");
tvName.setText(s.getName());
final Integer roll = Integer.parseInt(s.getRoll());
//ivpresent.setBackgroundColor(0);
final ViewHolder finalHolder1 = holder;
//final ViewHolder finalHolder = holder;
holder.presentButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
db1.updateUser(roll,"present");
finalHolder1.presentButton.setBackgroundColor(GREEN);
finalHolder1.absentButton.setBackgroundColor(0);
//v1.setTag(v.getTag());
//Log.d("present","Roll No: "+String.valueOf(roll));
finalHolder1.presentButton.setTag(Integer.toString(i));
notifyDataSetChanged();
}
});
holder.absentButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
db1.updateUser(roll,"absent");
finalHolder1.presentButton.setBackgroundColor(0);
finalHolder1.absentButton.setBackgroundColor(RED);
//view=null;
//Log.d("absent","Roll No: "+String.valueOf(roll));
finalHolder1.presentButton.setTag(Integer.toString(i));
notifyDataSetChanged();
}
});
return view;
}
public static class ViewHolder {
public ImageButton presentButton;
public ImageButton absentButton;
}
public class CustomListAdapter extends BaseAdapter {
private Activity activity;
private LayoutInflater inflater;
private List<studentInfo> students;
private boolean presentButton = false;
private boolean absentButton = false;
You need to add an else accordingly in your code, see below:
public View getView(final int i, View view, ViewGroup viewGroup) {
ViewHolder holder = new ViewHolder();
holder = null;
//view=null;
if (inflater == null) {
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
if (view == null) {
view = inflater.inflate(R.layout.student_list, null);
holder = new ViewHolder();
holder.presentButton = (ImageButton) view.findViewById(R.id.imageView);
holder.absentButton = (ImageButton) view.findViewById(R.id.imageView2);
holder.presentButton.setBackgroundColor(0);
holder.absentButton.setBackgroundColor(0);
view.setTag(holder);
}
else {
holder = (ViewHolder) view.getTag();
}
final SQLiteStudents db1 = new SQLiteStudents(activity.getApplicationContext());
final TextView tvName = (TextView) view.findViewById(R.id.tv_name);
final TextView tvRoll = (TextView) view.findViewById(R.id.tv_roll);
final studentInfo s = students.get(i);
tvRoll.setText(s.getRoll() + ".");
tvName.setText(s.getName());
final Integer roll = Integer.parseInt(s.getRoll());
//ivpresent.setBackgroundColor(0);
final ViewHolder finalHolder1 = holder;
//final ViewHolder finalHolder = holder;
holder.presentButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
db1.updateUser(roll,"present");
presentButton = true;
}
});
holder.absentButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
db1.updateUser(roll,"absent");
absentButton = true;
}
});
if(presentButton){
finalHolder1.presentButton.setBackgroundColor(GREEN);
finalHolder1.absentButton.setBackgroundColor(0);
//v1.setTag(v.getTag());
//Log.d("present","Roll No: "+String.valueOf(roll));
finalHolder1.presentButton.setTag(Integer.toString(i));
notifyDataSetChanged();
} else {
//set button to some default button like black
}
if(absentButton){
finalHolder1.presentButton.setBackgroundColor(0);
finalHolder1.absentButton.setBackgroundColor(RED);
//view=null;
//Log.d("absent","Roll No: "+String.valueOf(roll));
finalHolder1.presentButton.setTag(Integer.toString(i));
notifyDataSetChanged();
} else {
//set button to some default button like black
}
return view;
}

How to header in Gridview?

I have a gridview as you can see in the 1st picture . Now I want to add header to some specific part of the gridview as in 2nd picture. I am struggling to achieve this.
May I get any idea on how to achieve this view.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
holder = null;
Product productItem = (Product) productList.get(position);
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(R.layout.products_grid_item_layout, parent, false);
holder = new ViewHolder();
holder.productImage = (ImageView) row.findViewById(R.id.productImage);
holder.productImageClone = (ImageView) row.findViewById(R.id.productImageClone);
holder.detailsIcon = (ImageView) row.findViewById(R.id.detailsIcon);
holder.productTitle = (TextView) row.findViewById(R.id.productTitle);
holder.productSubTitle = (TextView) row.findViewById(R.id.productSubTitle);
holder.productQuantity = (TextView) row.findViewById(R.id.productQuantity);
holder.priceDollar = (TextView) row.findViewById(R.id.priceDollar);
holder.priceCent = (TextView) row.findViewById(R.id.priceCent);
holder.productCount = (TextView) row.findViewById(R.id.productCount);
holder.productGridLayout = (RelativeLayout) row.findViewById(R.id.productGridLayout);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
String price = productItem.getPrice().toString();
String[] pricearray;
pricearray = price.split("\\.");
holder.productTitle.setText(productItem.getTitle().toString());
holder.productSubTitle.setText(productItem.getSubtitle().toString());
holder.productQuantity.setText(productItem.getVolume().toString());
holder.priceDollar.setText(pricearray[0]+".");
holder.priceCent.setText(pricearray[1]);
if(productItem.getInCart()) {
holder.productCount.setVisibility(View.VISIBLE);
holder.productCount.setText(productItem.getVolume());
}
Picasso.with(context)
.load(productItem.getImageUrl())
.placeholder(R.drawable.favourites)
.error(R.drawable.favourites)
.into(holder.productImage);
Picasso.with(context)
.load(productItem.getImageUrl())
.placeholder(R.drawable.favourites)
.error(R.drawable.favourites)
.into(holder.productImageClone);
urlSlug = productItem.getUrlSlug();
holder.detailsIcon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final int position = currentGridView.getPositionForView(v);
Log.e("grid position", position+"");
Intent productDetailIntent = new Intent(context,ProductDetailActivity.class);
productDetailIntent.putExtra("url_slug", productList.get(position).getUrlSlug());
context.startActivity(productDetailIntent);
}
});
return row;
}
Try this way to add header
public class ListAsGridExampleAdapter extends ListAsGridBaseAdapter {
Integer[] mArray = new Integer[] {1,2,3,4,5,6,7,8,9,10,11,12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23};
private LayoutInflater mInflater;
public ListAsGridExampleAdapter(Context context) {
super(context);
mInflater = LayoutInflater.from(context);
}
#Override
public Integer getItem(int position) {
return mArray[position];
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemCount() {
return mArray.length;
}
#Override
protected View getItemView(int position, View view, ViewGroup parent) {
if (view == null) {
view = mInflater.inflate(R.layout.simple_list_item, null);
}
TextView tv = (TextView) view.findViewById(R.id.text);
tv.setText(String.valueOf(getItem(position)));
return view;
}
}
https://android.googlesource.com/platform/packages/apps/Gallery2/+/idea133/src/com/android/photos/views/HeaderGridView.java
https://github.com/liaohuqiu/android-GridViewWithHeaderAndFooter
Grid With Header and Footer
You can also Use StickyHeader

Why Listview showing duplicate entries with custom adapter android?

I created custom adapter to bind with listview but it's showing duplicate songs in listview. please check out the code and let me know if anything is wrong
public class UnfavoriteSongAdapter extends BaseAdapter
{
private Activity activity;
private ArrayList<Media> data;
private static LayoutInflater inflater = null;
private Context context;
public UnfavoriteSongAdapter(Context context, Activity a, ArrayList<Media> d) {
activity = a;
this.context = context;
data = d;
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
GenreFavoriteClickListner genreFavoriteClickListner;
public interface GenreFavoriteClickListner {
public void onFavoriteClickListner(int position,Media media);
}
public void setGenreFavoriteClickListner(GenreFavoriteClickListner genreFavoriteClickListner) {
this.genreFavoriteClickListner = genreFavoriteClickListner;
}
public static class ViewHolder {
public TextView textView_title, textView_artist, textView_time;
public CircleImageView circleImageView_albumphoto, circleImageView_favorite;
public ImageView imageView_play;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View vi = convertView;
final ViewHolder viewHolder;
try {
if (convertView == null) {
viewHolder = new ViewHolder();
final LayoutInflater inflater1 = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
vi = inflater1.inflate(R.layout.song_listitem_layout, null);
viewHolder.textView_title = (TextView) vi.findViewById(R.id.textView_song_songname);
viewHolder.textView_artist = (TextView) vi.findViewById(R.id.textView_song_artistname);
viewHolder.textView_time = (TextView) vi.findViewById(R.id.textView_song_time);
viewHolder.circleImageView_albumphoto = (CircleImageView) vi.findViewById(R.id.circleImageView_nowplaying_playing);
viewHolder.circleImageView_favorite = (CircleImageView) vi.findViewById(R.id.circleImageView_song_favorite);
viewHolder.imageView_play = (ImageView) vi.findViewById(R.id.imageView_song_playpause);
} else {
viewHolder = (ViewHolder) vi.getTag();
}
if (data.size() <= 0) {
//viewHolder.textview_albumtitle.setText("No Appointment");
} else {
final Media p = data.get(position);
viewHolder.textView_title.setText(p.getSongName());
viewHolder.textView_artist.setText(p.getArtistName());
long millis = Long.parseLong(p.getDuration());
String hms = ReusableModules.getCalculatedTime(millis);
viewHolder.textView_time.setText(hms);
String isplaying = p.getIsPlaying();
int playingid = R.mipmap.play;
if (isplaying != null) {
if(isplaying.contentEquals(Constants.ONE)){
playingid = R.mipmap.runing_music_play;
}
}
viewHolder.imageView_play.setImageResource(playingid);
ReusableModules.setFavoriteToggleButton(p.getIsFavorite(), viewHolder.circleImageView_favorite);
viewHolder.circleImageView_favorite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (genreFavoriteClickListner != null) {
genreFavoriteClickListner.onFavoriteClickListner(position,p);
}
}
});
final String finalUrl = p.getAlbumUrl();
viewHolder.circleImageView_albumphoto.post(new Runnable() {
#Override
public void run() {
BaseActivity.imageLoader.displayImage(finalUrl,
viewHolder.circleImageView_albumphoto, SplashScreenActivity.displayImageOptions, new SimpleImageLoadingListener() {
#Override
public void onLoadingComplete(Bitmap loadedImage) {
}
});
}
});
vi.setTag(p);
}
} catch (Exception e) {
}
return vi;
}
}
Change in getView() method like this.
viewHolder = new ViewHolder();
if (convertView == null) {
final LayoutInflater inflater1 = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
vi = inflater1.inflate(R.layout.song_listitem_layout, null);
viewHolder.textView_title = (TextView) vi.findViewById(R.id.textView_song_songname);
viewHolder.textView_artist = (TextView) vi.findViewById(R.id.textView_song_artistname);
viewHolder.textView_time = (TextView) vi.findViewById(R.id.textView_song_time);
viewHolder.circleImageView_albumphoto = (CircleImageView) vi.findViewById(R.id.circleImageView_nowplaying_playing);
viewHolder.circleImageView_favorite = (CircleImageView) vi.findViewById(R.id.circleImageView_song_favorite);
viewHolder.imageView_play = (ImageView) vi.findViewById(R.id.imageView_song_playpause);
and remove this
else {
viewHolder = (ViewHolder) vi.getTag();
}
in last of getView() method
convertView.setTag(holder);
try this and tell me it works or not?
move
vi.setTag(viewholder);
inside
if(convert==null){
viewHolder = new ViewHolder();
final LayoutInflater inflater1 = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
vi = inflater1.inflate(R.layout.song_listitem_layout, null);
viewHolder.textView_title = (TextView) vi.findViewById(R.id.textView_song_songname);
viewHolder.textView_artist = (TextView) vi.findViewById(R.id.textView_song_artistname);
viewHolder.textView_time = (TextView) vi.findViewById(R.id.textView_song_time);
viewHolder.circleImageView_albumphoto = (CircleImageView) vi.findViewById(R.id.circleImageView_nowplaying_playing);
viewHolder.circleImageView_favorite = (CircleImageView) vi.findViewById(R.id.circleImageView_song_favorite);
viewHolder.imageView_play = (ImageView) vi.findViewById(R.id.imageView_song_playpause);
// here
vi.setTag(viewholder);
}
and remove this:
final String finalUrl = p.getAlbumUrl();
viewHolder.circleImageView_albumphoto.post(new Runnable() {
#Override
public void run() {
BaseActivity.imageLoader.displayImage(finalUrl,
viewHolder.circleImageView_albumphoto, SplashScreenActivity.displayImageOptions, new SimpleImageLoadingListener() {
#Override
public void onLoadingComplete(Bitmap loadedImage) {
}
});
}
});
remove this **vi.setTag(p);**
Add vi.setTag(p) inside :
if(convertView == null){
vi.setTag(p);
}
set tag for view holder if view holder null. Add last line of code
if (convertView == null) {
viewHolder = new ViewHolder();
final LayoutInflater inflater1 = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
vi = inflater1.inflate(R.layout.song_listitem_layout, null);
viewHolder.textView_title = (TextView) vi.findViewById(R.id.textView_song_songname);
viewHolder.textView_artist = (TextView) vi.findViewById(R.id.textView_song_artistname);
viewHolder.textView_time = (TextView) vi.findViewById(R.id.textView_song_time);
viewHolder.circleImageView_albumphoto = (CircleImageView) vi.findViewById(R.id.circleImageView_nowplaying_playing);
viewHolder.circleImageView_favorite = (CircleImageView) vi.findViewById(R.id.circleImageView_song_favorite);
viewHolder.imageView_play = (ImageView) vi.findViewById(R.id.imageView_song_playpause);
/************ Set holder with LayoutInflater ************/
vi.setTag( viewHolder );
}
//check you data size getCount,its a good practice. not in getview method.
#Override
public int getCount() {
if(data!=null && data.size()> 0)
return data.size();
else
return 0;
}
I suggest you to replace getview method and check you data once because your adapter code seems perfect.

ListView - Wrong Recycling behavior with ViewHolder Design

Description:
I'm currently implementing a custom ListViewAdapter using the ViewHolder design pattern. The adapter is using a layout with a button that toggles the visibility of a RelativeLayout.
Problem:
When I click the button and the RelativeLayout is shown, everything seems to work fine until I scroll down. When I scroll down, I see that other listitems have been effected by the previous button click, so the RelativeLayout is visible on other (wrong) items. The item that is effected by the button click seems to be the one that is recycled when I scroll down. Please note that everything else works correct, texts etc. are set at the correct position.
Code:
CustomListAdapter
public class ItemsListAdapter extends ArrayAdapter<Item> {
private Context mContext;
private List<Item> mItems;
public ItemsListAdapter(Context context, int resource, List<Item> objects) {
super(context, resource);
mContext = context;
mItems = objects;
}
static class ViewHolder {
View mView;
boolean mExpanded;
public ViewHolder(View view, boolean expanded)
{
mView = view;
mExpanded = expanded;
}
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
final Item item = getItem(position);
final ViewHolder holder;
if (v == null) {
LayoutInflater mInflater = (LayoutInflater)
mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
v = mInflater.inflate(R.layout.custom_list_item, null);
holder = new ViewHolder(v, false);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
if(item != null)
{
TextView tvName = (TextView) holder.mView.findViewById(R.id.tv_name);
tvName.setText(item.getName());
RelativeLayout rlExpand = (RelativeLayout) holder.mView.findViewById(R.id.rl_expand);
if(holder.mExpanded) {
rlExpand.setVisibility(View.VISIBLE);
}
else {
rlExpand.setVisibility(View.GONE);
}
TextView tvDescription = (TextView) holder.mView.findViewById(R.id.tv_description);
if(tvDescription != null)
tvDescription.setText(item.getDescription());
final ImageButton ibExpand = (ImageButton) holder.mView.findViewById(R.id.ib_expand);
ibExpand.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RelativeLayout rlExpand = (RelativeLayout) holder.mView.findViewById(R.id.rl_expand);
if (rlExpand.getVisibility() == View.GONE) {
v.setVisibility(View.INVISIBLE);
rlExpand.setVisibility(View.VISIBLE);
holder.mExpanded = true;
}
}
});
ImageButton ibCollapse = (ImageButton) holder.mView.findViewById(R.id.ib_collapse);
ibCollapse.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RelativeLayout rlExpand = (RelativeLayout) holder.mView.findViewById(R.id.rl_expand);
ibExpand.setVisibility(View.VISIBLE);
rlExpand.setVisibility(View.GONE);
holder.mExpanded = false;
}
});
}
return v;
}
#Override
public int getCount() {
return mItems.size();
}
#Override
public Truism getItem(int position) {
return mItems.get(position);
}
Any help is highly appreciated! Thank you in advance!
Try to change:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
final Item item = getItem(position);
final ViewHolder holder;
if (v == null) {
LayoutInflater mInflater = (LayoutInflater)
mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
v = mInflater.inflate(R.layout.custom_list_item, null);
holder = new ViewHolder(v, false);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
if(item != null)
{
TextView tvName = (TextView) holder.mView.findViewById(R.id.tv_name);
tvName.setText(item.getName());
RelativeLayout rlExpand = (RelativeLayout) holder.mView.findViewById(R.id.rl_expand);
if(item.isExpanded) {
rlExpand.setVisibility(View.VISIBLE);
}
else {
rlExpand.setVisibility(View.GONE);
}
TextView tvDescription = (TextView) holder.mView.findViewById(R.id.tv_description);
if(tvDescription != null)
tvDescription.setText(item.getDescription());
[...]
}
return v;
}
Change holder.mExpanded to item.isExpanded

Android: OnClick ImageView not change correct Image

I am creating an app where there are images in a custom Listview. The database put a picture or another. Clicking the image has to change. But when I click the image is not changed at the correct ImageView. It changes other ImageView.
I need any help. thanks
public View getView(final int position, View convertView, ViewGroup parent) {
View v = convertView;
final MonumentosHolder holder = new MonumentosHolder();
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.listview_row, null);
TextView tv = (TextView) v.findViewById(R.id.textoListviewNombre);
ImageView img3 = (ImageView) v.findViewById(R.id.imagenVisto);
holder.texto = tv;
holder.imagenVisto = img3;
v.setTag(holder);
}
else {
holder = (MonumentosHolder) v.getTag();
}
holder.position = position;
final MonumentosObj p = monumentosLista.get(position);
holder.texto.setText(p.getNombre());
if (p.getVisto().equals("n")) {
holder.imagenVisto.setImageResource(R.drawable.vistorojo);
} else {
holder.imagenVisto.setImageResource(R.drawable.vistoverde);
}
holder.imagenVisto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MonumentosObj p1 = monumentosLista.get(holder.position);
if (p1.getVisto().equals("s")) {
holder.imagenVisto.setImageResource(R.drawable.vistorojo);
p1.setVisto("n");
} else {
holder.imagenVisto.setImageResource(R.drawable.vistoverde);
p1.setVisto("s");
}
MonumentosAdapter.updateMonumentos(p1);
MonumentosObj p = monumentosLista.get(holder.position);
}
});
imageLoader.displayImage(imageUrls[position], holder.imagen, options, animateFirstListener);
return v;
}
EDIT
Onclick not change the correct image. But when I scroll the listview to below and and return to top, the correct image has changed...
I think that bit of code maybe wrong :
holder.imagenVisto.setOnClickListener(new View.OnClickListener() {
private int pos = position;
#Override
public void onClick(View v) {
MonumentosObj p1 = monumentosLista.get(pos);
Try to store position inside holder object and when assigning it in onClick Listener instead
private int pos = position;
do
private int pos = holder.getPosition()
Remember that android ListViews are not loading all items at one time it just loads thats what is visible and few items beyond that,
Also remember that positions of your items in your Arrays doesn't change you may use it somehow :)
try to change
holder.imagenVisto.setOnClickListener(new View.OnClickListener()
by
holder.imagenVisto.setOnClickListener(new OnClickListener()
I think your click listener affect early items in your list!
do this:
put a long item in your viewHolder:
class MonumentosHolder {
.
.
.
long position;
}
and then in your getView, set the holder positon:
View v = convertView;
--EDITED--
final MonumentosHolder holder = new MonumentosHolder();
--END EDITED--
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.listview_row, null);
TextView tv = (TextView) v.findViewById(R.id.textoListviewNombre);
ImageView img3 = (ImageView) v.findViewById(R.id.imagenVisto);
holder.texto = tv;
holder.imagenVisto = img3;
v.setTag(holder);
}
else {
holder = (MonumentosHolder) v.getTag();
}
**holder.postion = position;**
and then click listener would be like this:
EDITED
holder.imagenVisto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MonumentosObj p1 = monumentosLista.get(**holder.position**);
if (p1.getVisto().equals("s")) {
holder.imagenVisto.setImageResource(R.drawable.vistorojo);
p1.setVisto("n");
} else {
holder.imagenVisto.setImageResource(R.drawable.vistoverde);
p1.setVisto("s");
}
MonumentosAdapter.updateMonumentos(p1);
MonumentosObj p = monumentosLista.get(holder.position);
}
});
EDIT 4
remove the final modifier from holder, define another MonumentosHolder named finalHolder like this:
public View getView(final int position, View convertView, ViewGroup parent) {
View v = convertView;
MonumentosHolder holder = new MonumentosHolder();
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.listview_row, null);
TextView tv = (TextView) v.findViewById(R.id.textoListviewNombre);
ImageView img3 = (ImageView) v.findViewById(R.id.imagenVisto);
holder.texto = tv;
holder.imagenVisto = img3;
v.setTag(holder);
}
else {
holder = (MonumentosHolder) v.getTag();
}
holder.position = position;
final MonumentosObj p = monumentosLista.get(position);
holder.texto.setText(p.getNombre());
if (p.getVisto().equals("n")) {
holder.imagenVisto.setImageResource(R.drawable.vistorojo);
} else {
holder.imagenVisto.setImageResource(R.drawable.vistoverde);
}
final MonumentosHolder finalHolder = holder;
holder.imagenVisto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MonumentosObj p1 = monumentosLista.get(finalHolder.position);
if (p1.getVisto().equals("s")) {
holder.imagenVisto.setImageResource(R.drawable.vistorojo);
p1.setVisto("n");
} else {
holder.imagenVisto.setImageResource(R.drawable.vistoverde);
p1.setVisto("s");
}
MonumentosAdapter.updateMonumentos(p1);
MonumentosObj p = monumentosLista.get(finalHolder.position);
}
});
imageLoader.displayImage(imageUrls[position], holder.imagen, options, animateFirstListener);
return v;
}

Categories

Resources