【问题标题】:Changing a icon in ActionBar depending on a condition根据条件更改 ActionBar 中的图标
【发布时间】: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"/>

【问题讨论】:

    标签: java android boolean logic android-actionbar


    【解决方案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 的,它们下面的范围才能使用它们。但是,如果您将其设为全局并在上面声明,则不需要是最终的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-24
      • 2015-11-23
      • 2020-06-22
      • 2020-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多