-1

I have a ListView that shows list items (duh). When you click on a list item, another Activity opens. Part of the list item layout is a grey star, an ImageView. When you click on this ImageView, I don't want to open another Activity, but I want to change the color of the star to green (= mark the item as favourite) or back (= mark it as not favourite). I managed to do that with an OnClickListener, loading another ImageView on Click, and refreshing the adapter. But for the ImageView to change, after clicking it I need to leave the Activity and enter again. It doesn't refresh instantly. Why, and how can I change that? I've tried lots of different versions, so far nothing works. My ListViewAdapter extends BaseAdapter. Thank you!

public class ListViewAdapterKeysAToZ extends BaseAdapter {

private ArrayList<KeyTagIntern> keyTags;
private ObservableArrayList<KeyTagIntern> list;
private Context context;
TextView name;
TextView place;
ImageView star, favoriteStar;    

public ListViewAdapterKeysAToZ(Context context, ObservableArrayList<KeyTagIntern> list) 

{
    this.context = context;
    this.list = list;

    keyTags = new ArrayList<>();

    for (KeyTagIntern keytag : list) {
        keyTags.add(keytag);
    }
    //(....)
}

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

KeyTagIntern key = (KeyTagIntern) getItem(position);

  if (convertView == null) {
                convertView = LayoutInflater.from(context).inflate(R.layout.list_item_keys, parent, false);
            }

            name = (TextView) convertView.findViewById(R.id.text_keylist_item);
            name.setText(key.getName());

            place = (TextView) convertView.findViewById(R.id.text_keylist_item_place);
            place.setText(key.getPlace());

            star = (ImageView) convertView.findViewById(R.id.right_icon_keylist_item);
            favoriteStar = (ImageView) convertView.findViewById(R.id.right_icon_keylist_item_favorite);

if (key.isFavorite())
{ 
    star.setVisibility(View.INVISIBLE);
    favoriteStar.setVisibility(View.VISIBLE)

    favoriteStar.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            // This makes key.isFavourite() = false for the next time
            Paper.book().delete(FAVORIT + String.valueOf(key.getKeyTagID()));

            //Since notifyDataSetChanged() didn't work for me, I tried this - but no change
            int index = list.indexOf(key);
            list.remove(index);
            list.add(index, key);

            keyTags = new ArrayList<>();

            for (KeyTagIntern keytag : list) {
                keyTags.add(keytag);
            }
            notifyDataSetChanged();
        }
    });
}

// Then do the opposite for if (!key.isFavourite())

Und hier das xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/list_item_keys"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/MiddleDarkGrey">


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/btn_list_item_keys"
    android:layout_width="match_parent"
    android:layout_height="@dimen/height_list_item"
    android:layout_marginBottom="3dp"
    android:layout_marginLeft="20dp"
    android:layout_marginRight="20dp"
    android:layout_marginTop="3dp"
    android:background="@drawable/white_list_item"
    android:paddingLeft="13dp"
    android:paddingRight="10dp">

    <ImageView
        android:id="@+id/icon_keylist_item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_centerVertical="true"
        android:visibility="visible"
        app:srcCompat="@drawable/ic_key" />

    <ImageView
        android:id="@+id/icon_reserved"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/chb_add_key"
        android:layout_centerVertical="true"
        android:visibility="invisible"
        app:srcCompat="@drawable/ic_reservate_orange" />

    <ImageView
        android:id="@+id/icon_taken"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/chb_add_key"
        android:layout_centerVertical="true"
        android:visibility="invisible"
        app:srcCompat="@drawable/ic_taken_red" />

    <TextView
        android:id="@+id/text_keylist_item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginStart="10dp"
        android:layout_toEndOf="@+id/icon_keylist_item"
        android:layout_toRightOf="@+id/icon_keylist_item"
        android:gravity="center_vertical"
        android:layout_centerVertical="true"
        android:text="Text"
        android:textColor="@color/DarkGrey"
        android:textSize="@dimen/text_list_item" />

    <TextView
        android:id="@+id/text_keylist_item_place"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/text_keylist_item"
        android:layout_alignLeft="@+id/text_keylist_item"
        android:layout_marginLeft="2dp"
        android:layout_marginBottom="5dp"
        android:text="Where is the key?"
        android:textColor="@color/DarkGrey"
        android:textSize="@dimen/text_list_item_sub" />

    <ImageView
        android:id="@+id/right_icon_keylist_item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        app:srcCompat="@drawable/ic_fav_green" />

    <ImageView
        android:id="@+id/right_icon_keylist_item_favorite"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:srcCompat="@drawable/ic_fav_chosen"
        android:visibility="invisible"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true" />

</RelativeLayout>

Mira
  • 81
  • 6
  • 1
    Can you post the code where you actually set up the view? – Mars Oct 18 '17 at 06:47
  • It doesn't look like you're actually setting up your view in the getView function. We can't see what star or favoriteStar are referencing – Mars Oct 18 '17 at 06:50
  • oh, sorry - i left it out, since i didn't think there could be anything problematic in that part of the code. now i added that part. – Mira Oct 18 '17 at 08:28
  • Hmm, I don't see anything that stands out. Are you sure that you're entering the right places? Have you set breakpoints already? Specifically, is it the correct key? Is it being deleted? is the list correct, or is it set to the original list? Is isFavorite() evaluating correctly? – Mars Oct 18 '17 at 08:39
  • One more check, since I don't think it's an issue with images, but for the "opposite" code, are you connecting to the correct star? If it's invisible and the size gets set to zero, you won't be able to click it – Mars Oct 18 '17 at 08:47
  • 1
    Thank you Mars, I tried all of it - in the end the answer was rather stupid, as it is so often, and you couldn't have helped me since I excluded the code at the beginning of my adapter class. It actually worked the whole time, but I didn't see it, since the listitem at the very end of the list was changed, not the selected one. This was due to me declaring the variables at the beginning of the class, rather than inside the getView method. – Mira Oct 18 '17 at 10:02

2 Answers2

0

I think your approach should be something like this.
rather hiding and displaying an image just change source of it!

if (key.isFavorite())
{ 
favoriteStar.setImageResource(R.drawable.aaa);

favoriteStar.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) 
    favoriteStar.setImageResource(R.drawable.bbb);
    // and vice-versa

and I don't thing you will be needing notifyDataSetChanged(); as you are making no changes in the Listdata actually!

phpdroid
  • 1,642
  • 1
  • 18
  • 36
  • I don't think it matters if I change the source or set the visibility. And you should use notifyDataSetChanged() - it's the cleaner way to code here, I think. – Mira Oct 18 '17 at 09:53
  • the clear way of coding ?? really I don't think so, you have an idea why it is used? – phpdroid Oct 18 '17 at 09:55
  • The data has been changed - notifying the responsible adapter about it instead of merely changing the surface seems cleaner to me. And I've checked Stackoverflow extensively about this topic before posting this question, and every upvoted answer included calling notifyDataSetChanged() in one way or another – Mira Oct 18 '17 at 10:13
  • `notifyDataSetChanged()` used when you make changes in data not for change in a view I have developed similar functionality here https://play.google.com/store/apps/details?id=in.webic.moviepal – phpdroid Oct 18 '17 at 11:29
0

In the end the answer was rather stupid, as it is so often, and you guys couldn't have helped me since I excluded the code at the beginning of my adapter class (added it now). It actually worked the whole time, but I didn't see it, since the listitem at the very end of the list was changed, not the selected one. This was due to me declaring the variables at the beginning of the adapter class, rather than inside the getView method.

I changed it to this and now it works perfectly:

public class ListViewAdapterKeysAToZ extends BaseAdapter {

private ArrayList<KeyTagIntern> keyTags;
private ObservableArrayList<KeyTagIntern> list;
private Context context;


public ListViewAdapterKeysAToZ(Context context, ObservableArrayList<KeyTagIntern> list) {
    this.context = context;
    this.list = list;

    keyTags = new ArrayList<>();

    for (KeyTagIntern keytag : list) {
        keyTags.add(keytag);
    }
// (...)


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

    KeyTagIntern key = (KeyTagIntern) getItem(position);

    TextView name;
    TextView place;
    ImageView star, favoriteStar;

            if (convertView == null) {
                convertView = LayoutInflater.from(context).inflate(R.layout.list_item_keys, parent, false);
            }

            name = (TextView) convertView.findViewById(R.id.text_keylist_item);
            name.setText(key.getName());

            place = (TextView) convertView.findViewById(R.id.text_keylist_item_place);
            place.setText(key.getPlace());

            star = (ImageView) convertView.findViewById(R.id.right_icon_keylist_item);
            favoriteStar = (ImageView) convertView.findViewById(R.id.right_icon_keylist_item_favorite);

            if (key.isFavorite()) {
                star.setVisibility(View.INVISIBLE);
                favoriteStar.setVisibility(View.VISIBLE);
            }else {
                star.setVisibility(View.VISIBLE);
                favoriteStar.setVisibility(View.INVISIBLE);
            }

            star.setOnClickListener(v -> {
                key.setFavorite(true);
                Paper.book().write(FAVORIT + String.valueOf(key.getKeyTagID()), true);
                notifyDataSetChanged();
            });

            favoriteStar.setOnClickListener(v -> {
                key.setFavorite(false);
                Paper.book().delete(FAVORIT + String.valueOf(key.getKeyTagID()));
                notifyDataSetChanged();
            });
Mira
  • 81
  • 6
  • Does this still work? if star and favorite star are in the same place, it seems like the upper one should receive the click (or both). Also, where you declare the variables shouldn't matter... – Mars Oct 19 '17 at 00:20
  • The substantial changes that I see are your new setFavorite method (which might mean that your isFavorite method was evaluating incorrectly before), and the fact that you set onClickListeners for both stars, regardless of current favorite state – Mars Oct 19 '17 at 00:38
  • Because you weren't unsetting the onClickListener for the un-used state, if both were triggering, you were likely triggering the onClickListener on another cell as well. – Mars Oct 19 '17 at 01:01