Search code examples
androidandroid-listviewandroid-cursoradapter

Image appearing in first entry of ListView when it should not appear


This is the right-hand side of a ListView in an application I am working on.

There are two stars here. There should only be one.

As you can see, an ImageView displaying a star shows up twice in a list of 9 entries.

This is the BindView method that this ListView's CursorAdapter uses:

@Override
public void bindView(View v, Context context, Cursor c) {
    AQuery aq = new AQuery(v);
    MyDatabaseHelper helper = new MyDatabaseHelper(context); //Used for various bits of text-setting. Is largely unrelated to the question.
    boolean isDefault = (c.getShort(c.getColumnIndexOrThrow(MyDatabaseHelper.DEFAULT))==1);
    Log.d("Binding account to view", "Entry "+currentID+"isDefault: "+isDefault);
    v.setTag(isDefault);
    if (isDefault) {
        aq.id(R.id.favStar).visible(); //favStar defaults to GONE.
    }
    helper.close();
}

As you can see, it checks if a column in my database reads 1 and then stores that bit of boolean math in a variable. With that variable, it tags the View, reports the status of that variable, then it makes the star visible if and only if the variable is true.

This is the log output from the list being populated, before the 9th entry was added:

02-28 10:50:23.381: D/Binding account to view(20759): Entry 1isDefault: false
02-28 10:50:23.397: D/Binding account to view(20759): Entry 2isDefault: false
02-28 10:50:23.413: D/Binding account to view(20759): Entry 3isDefault: false
02-28 10:50:23.420: D/Binding account to view(20759): Entry 4isDefault: false
02-28 10:50:23.436: D/Binding account to view(20759): Entry 5isDefault: false
02-28 10:50:23.444: D/Binding account to view(20759): Entry 6isDefault: false
02-28 10:50:23.459: D/Binding account to view(20759): Entry 7isDefault: false
02-28 10:50:23.475: D/Binding account to view(20759): Entry 8isDefault: true
02-28 10:50:23.498: D/Binding account to view(20759): Entry 1isDefault: false
02-28 10:50:23.506: D/Binding account to view(20759): Entry 2isDefault: false
02-28 10:50:23.530: D/Binding account to view(20759): Entry 3isDefault: false
02-28 10:50:23.553: D/dalvikvm(20759): GC_CONCURRENT freed 122K, 2% free 11069K/11271K, paused 3ms+15ms, total 43ms
02-28 10:50:23.553: D/Binding account to view(20759): Entry 4isDefault: false
02-28 10:50:23.577: D/Binding account to view(20759): Entry 5isDefault: false
02-28 10:50:23.592: D/Binding account to view(20759): Entry 6isDefault: false
02-28 10:50:23.600: D/Binding account to view(20759): Entry 7isDefault: false
02-28 10:50:23.616: D/Binding account to view(20759): Entry 8isDefault: true

(Adding the 9th entry just adds an "Entry 9isDefault:false" to the log output.)

Can anyone tell me why my list has a star appearing where the debug logs are stating one should not be appearing? Neither the ListFragment that this ListView appears in, nor the Activity that houses the ListFragment make any references to R.id.favStar anywhere.

To further elaborate: I've also tried this without using AQuery (using FindViewById() and setVisible()) and the results did not change to the expected results shown in the debug logs. The bugged star always appears in the first position, and only appears if the other star in the list is supposed to appear. (The DatabaseHelper class sets all items in the database to ISDEFAULT=0 before setting something with ISDEFAULT=1.) Bizarrely enough, using the template the ADT gives you for a Master/Detail Flow, this bug is not replicatable on my Nexus 7, but can be found on both my Galaxy Nexus and the emulator.


Solution

  • You never hide your favStar view if isDefault is false. If your element is set to true and you show the view, the star will be visible until you hide it again. When the view gets recycled, the star will still show even if it wasn't supposed. You don't see it on your nexus 7 because you may not have enough elements for this to happen as its screen is taller than a phone's. Anyway, changing your code to something like should fix it:

    if (isDefault) {
      aq.id(R.id.favStar).visible(); //favStar defaults to GONE.
    } else {
      //set favStar to View.GONE here
    }