Hey Guys I am working right now on a University project and have some problems which I found out randomly. Actually, I have to create an app (android) for an upcoming event where the user can see all the events in an overview and can tag his favorite ones.
I have a listview object, which is displaying all the items from a List<> I wanna give the opportunity that the user can tag his favorite events which shall appear in a new fragment but I have problems with the changing icon. When you tag the first item in the list, it also tags every fourth item in the list additionally. I don't know why and it would be great if you can help! :)
the selector for the Image View
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/ic_bookmark_black_24dp_copy_3" />
<item android:state_selected="false" android:drawable="@drawable/ic_bookmark_border_black_24dp_copy_3" />
<item android:drawable="@drawable/ic_bookmark_black_24dp_copy_3" />
</selector>
the adapter including the activating function to change the icon
public class CustomArrayAdapter extends BaseAdapter{
private List<EventItem> listData;
private LayoutInflater layoutInflater;
private Context context;
static class ViewHolder {
TextView titleView;
TextView descriptionView;
TextView authorView;
TextView reportedDateView;
TextView locationView;
ImageView favorite;
}
public CustomArrayAdapter(Context context, List<EventItem> listData) {
this.context = context;
this.listData = listData;
Collections.sort(listData);
}
@Override
public int getCount() {
return listData.size();
}
@Override
public Object getItem(int position) {
return listData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
layoutInflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.list_event_item, null);
holder = new ViewHolder();
holder.titleView = (TextView) convertView.findViewById(R.id.title);
holder.authorView = (TextView) convertView.findViewById(R.id.author);
holder.descriptionView = (TextView) convertView.findViewById(R.id.description);
holder.locationView = (TextView) convertView.findViewById(R.id.location);
holder.reportedDateView = (TextView) convertView.findViewById(R.id.time);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.titleView.setText(listData.get(position).getTitle());
holder.authorView.setText(listData.get(position).getAuthor());
holder.descriptionView.setText(listData.get(position).getDescription());
holder.locationView.setText(listData.get(position).getLocation());
holder.reportedDateView.setText(getTime(position));
holder.favorite = (ImageView) convertView.findViewById(R.id.bookmark);
holder.favorite.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(view.isSelected()) {
System.out.println("Position: ");
view.setSelected(false);
}else{
view.setSelected(true);
}
}
});
return convertView;
}
private String getTime(int position) {
Date start = listData.get(position).getStartTime();
Date end = listData.get(position).getEndTime();
String startTime = start.toString();
String endTime = end.toString();
return String.format("%1s%2s%3s", start.toString().substring(11, 19), " - ", end.toString().substring(11, 19));
}
}
And here my Image view out of the xml file where all the other views where styled
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/description"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginEnd="8dp"
android:src="@drawable/bookmark_icon_selector"
android:tint="@color/colorDhdPrimary"
android:id="@+id/bookmark"
/>
and here the list view in the separate XML.
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:id="@+id/list_container">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/list_event"
app:layout_constraintBottom_toBottomOf="@+id/list_container"
app:layout_constraintLeft_toLeftOf="@+id/list_container"
app:layout_constraintRight_toRightOf="@+id/list_container"
app:layout_constraintTop_toTopOf="@+id/list_container"
/>
Solution can be multiple . One way to do this is just add a boolean in your EventItem
POJO.
class EventItem{
boolean isSelected;
}
Now toggle this boolean onClick
.
final int pos=position;
holder.favorite.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listData.get(pos).isSelected=!listData.get(posi).isSelected;
notifyDataSetChanged();
}
});
And in onBindViewHolder
just check for boolean.
if(listData.get(position).isSelected){
holder.favorite.setSelected(true);
}else{
holder.favorite.setSelected(false);
}