【问题标题】:Edit Options Menu after receiving data from an asyncronous task从异步任务接收数据后编辑选项菜单
【发布时间】:2014-02-16 13:43:44
【问题描述】:

我正在我的应用中实施应用内结算服务。我在onCreate() 中设置了对IabHelper.queryInventoryAsync() 的调用以检索以前的购买。如果购买了商品,我将全局布尔变量设置为 true。同时,在onCreateOptionsMenu() 中,我检查该变量是否删除菜单项。我的问题是onCreateOptionsMenu(),正如预期的那样,有时在异步任务完成设置我的布尔变量之前被调用。我需要一个解决方案来告诉onCreateOptionsMenu() 等待该任务设置布尔值,以便它可以相应地创建菜单。详细代码如下:

@Override
protected void onCreate(Bundle savedInstanceState) {  

//other  stuff...

   helper.queryInventoryAsync(new IabHelper.QueryInventoryFinishedListener() {
                public void onQueryInventoryFinished(IabResult result,
                                                     Inventory inventory) {

                    if (result.isFailure()) {
                        // handle error here   
                        return;                        
                    }

                    if (inventory.hasPurchase(REMOVE_ADS_SKU)) {  
                        //item purchased. set control variable
                        isNoAds = true;
                    } 

                }
            });
}

@Override
public boolean onCreateOptionsMenu(final Menu menu) {

    getMenuInflater().inflate(R.menu.main, menu);

    //if the control variable is true, remove the option to buy ad-free version
    if (isNoAds) menu.removeItem(R.id.action_remove_ads);

    return super.onCreateOptionsMenu(menu);
}

【问题讨论】:

    标签: android in-app-purchase android-optionsmenu


    【解决方案1】:

    我发现最可靠的方法是使整个菜单无效。因此,当您获得异步结果(在 onQueryInventoryFinished 中)时,只需调用:

    invalidateOptionsMenu();
    

    或者,如果您使用的是 FragmentActivitySherlockFragmentActivityActionBarActivity

    supportInvalidateOptionsMenu();
    

    通过这种方式,菜单将被重新创建,您可以根据需要安全地添加或删除项目。

    【讨论】:

    • 这似乎彻底解决了问题,因为 invalidateOptionsMenu() 似乎不需要对菜单本身的任何引用,并且在调用时发生异常时没有明显的风险菜单尚未创建,这是我关心的问题,因为该方法位于 onCreate() 中。我确实想到了这个解决方案,但我使用的是 api 10,我错过了这个方法有兼容版本的事实 :) 非常感谢!
    【解决方案2】:

    也许使用onPrepareOptionMenu 可能会成功。文档 (http://developer.android.com/reference/android/app/Activity.html#onPrepareOptionsMenu%28android.view.Menu%29) 声明它用于准备应显示的内容。您将 xml 膨胀保留在 onCreateOptionsMenu 中,然后执行以下操作:

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        menu.findItem(R.id.action_remove_ads).setVisible(!isNoAds);
        return super.onPrepareOptionsMenu(menu);
    }
    

    您仍然在onCreate 方法中将isNoAds 变量初始化为true,以确保它不会立即显示。

    【讨论】:

    • 我相信这是最直接的解决方案,但是如果在显示 ui 后立即打开菜单,当任务尚未设置变量时,MenuItem 仍然可见。有一个常见的用途(通常没有人在打开应用程序后立即打开菜单),这可能没问题,但上面的解决方案似乎是最强大的。感谢您的回答!
    • 您可以简单地在 onCreate 方法中将 isNoAds 初始化为 true,这样它就不会被看到并且您无需进行进一步的处理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-10
    • 1970-01-01
    • 2017-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多