I am updating a record in a SQLite database when the user presses an icon on the ActionBar. The information being updated is a flag that adds a record to a Favourites page.
PROBLEM
When the user adds or removes the record to favourites, I would like the icon in the ActionBar to change. I have a full star icon and a empty star icon.
The setIcon method displays the the full star icon if the record is a favourite, and a empty star icon if the record is not a favourite.
In the code below you will see I am using a boolean isInFavourite, which is true when String fav = "y".
When entering the Activity, the icon displayed is correct.
When the user clicks on the icon to invoke the onMenuItemClick() method, the record is successfully updated but the icon does not change.
I am unable to change the boolean isInFavourite when the record has been updated because Eclipse wants all the variables to be set as final
Can anyone help me change the icon to once the record has been updated.
@Override
public boolean onCreateOptionsMenu(Menu menu) {
db = new DBHelper(this);
db.createDataBase();
db.openDataBase();
Bundle bundle = getIntent().getExtras();
final String rowid = bundle.getString("id");
final String fav = bundle.getString("fav");
//Boolean to check if record is a favourite
final boolean isInFavourite = fav.contentEquals("y");
menu.add("Add to Favourites")
.setOnMenuItemClickListener(new OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
String toggle;
String message;
//Logic to add or remove row from recording.
if (isInFavourite) {
toggle = "n";
message = "Recipe removed from Favourites";
} else {
toggle = "y";
message = "Recipe added to Favourites";
}
//Update favourite record in database
db.updateFavourite(rowid, toggle);
db.close();
Toast.makeText(getApplicationContext(), message,
Toast.LENGTH_LONG).show();
return true;
}
})
//Set icon depending on whether record is a favourite or not.
.setIcon(isInFavourite ? R.drawable.fav_true : R.drawable.fav_false)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
return true;
}
Thanks to @dmon for the solution
SOLUTION
private DBHelper db = null;
public String fav = null;
public String rowid = null;
public boolean isFav;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
Bundle bundle = getIntent().getExtras();
rowid = bundle.getString("id");
fav = bundle.getString("fav");
if (fav.contentEquals("y")) {
isFav = true;
} else {
isFav = false;
}
try {
db = new DBHelper(this);
db.createDataBase();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.menu_settings, menu);
return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem fave = menu.findItem(R.id.add);
MenuItem unfave = menu.findItem(R.id.remove);
fave.setVisible(isFav);
unfave.setVisible(!isFav);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
case R.id.add:
fav = "n";
isFav = false;
updateFav();
supportInvalidateOptionsMenu();
Toast("Removed from Favourites");
return true;
case R.id.remove:
fav = "y";
isFav = true;
updateFav();
supportInvalidateOptionsMenu();
Toast("Added to Favourites");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void updateFav (){
db.openDataBase();
db.updateFavourite(rowid, fav);
db.close();
}
XML File: res/menu/menu_settings.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/add"
android:icon="@drawable/good"
android:showAsAction="always"
/>
<item
android:id="@+id/remove"
android:icon="@drawable/bad"
android:showAsAction="always"/>
The easiest way is to just provide two different buttons and hide/show them accordingly:
Then you invalidate the options menu when the state has changed. Note that you have to have a global variable that has the current state of the item (where
isFaveis coming from)