根据条件更改 ActionBar 中的图标
Posted
技术标签:
【中文标题】根据条件更改 ActionBar 中的图标【英文标题】:Changing a icon in ActionBar depending on a condition 【发布时间】:2012-08-05 02:04:12 【问题描述】:当用户按下ActionBar
上的图标时,我正在更新 SQLite 数据库中的记录。正在更新的信息是将记录添加到收藏夹页面的标志。
问题
当用户将记录添加或删除到收藏夹时,我希望ActionBar
中的图标发生变化。我有一个完整的星形图标和一个空的星形图标。
setIcon
方法如果记录是收藏夹则显示完整的星形图标,如果记录不是收藏夹则显示空星形图标。
在下面的代码中,您将看到我使用的是boolean isInFavourite
,当String fav = "y"
时是true
。
输入Activity
时,显示的icon
是正确的。
当用户点击icon
调用onMenuItemClick()
方法时,记录更新成功,但icon
没有改变。
当记录已更新时,我无法更改 boolean isInFavourite
,因为 Eclipse 想要将所有变量设置为 final
任何人都可以帮我将图标更改为记录更新后。
@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;
感谢@dmon 的解决方案
解决方案
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 文件: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"/>
【问题讨论】:
【参考方案1】:最简单的方法是只提供两个不同的按钮并相应地隐藏/显示它们:
@Override
public boolean onCreateOptionsMenu(Menu menu)
MenuInflater inf = new MenuInflater(this);
inf.inflate(R.menu.menu_xml, menu);
return true;
@Override
public boolean onPrepareOptionsMenu(Menu menu)
MenuItem fave = menu.findItem(R.id.favorite);
MenuItem unfave = menu.findItem(R.id.unfavorite);
fave.setVisible(!isFave);
unfave.setVisible(isFave);
return true;
然后,当状态改变时,您使选项菜单无效。请注意,您必须有一个具有项目当前状态的全局变量(isFave
的来源)
invalidateOptionsMenu();
【讨论】:
我需要为菜单项制作自己的 xml 文件吗? 不一定,你可以按照你一直在做的方式去做,而不是把它膨胀起来。也就是说,xml 更干净。 尝试使用您的解决方案。什么方法应该有我的数据库逻辑?我发现使用 java 而不是 xml 创建菜单更容易。 嗯,如果我没记错的话,我会将您的数据库代码移动到您的onCreate
,它在 onCreateOptionsMenu()
之前运行。将记录信息保存在类变量中,以便您可以在onCreateOptionsMenu
中使用它。
使用您的解决方案让它工作!我已将数据库逻辑添加到 onOptionItemSelected()
方法中。我正在使用 ActionBarSherlock。你知道invalidateOptionsMenu()
是否适用于 Froyo 和 Gingerbread 吗?【参考方案2】:
将 isInFavourite 变量设为全局字段(在方法之外声明它,就在类中)。任何局部变量都必须是 final 的,它们下面的范围才能使用它们。但是,如果您将其设为全局并在上面声明,则不需要是最终的。
【讨论】:
以上是关于根据条件更改 ActionBar 中的图标的主要内容,如果未能解决你的问题,请参考以下文章