7

AsynctaskLoader从 Activity 启动an 时OnCreate(),它会在操作栏菜单膨胀之前完成其工作并调用onLoaderFinished() ,即在onCreateOptionsMenu()调用之前。

我需要根据加载程序的结果更改一些操作菜单项。什么方法可以解决这个问题?

更新:这发生在方向改变时。我在调试器中观察这个序列:

  1. 应用程序开始:onCreate()-> onCreateOptionsMenu()->onLoadFinished()
  2. 旋转到横向:onCreate()-> onLoadFinished()->onCreateOptionsMenu()
  3. 旋转回纵向:onCreate()-> onLoadFinished()->onCreateOptionsMenu()
4

3 回答 3

2

我在尝试调用时遇到了同样的情况shareActionProvider.setShareIntent()onLoadFinished()这取决于 shareActionProvider 在onCreateOptionsMenu().

我的解决方案是将我的 Intent 和 ShareActionProvider 都限定为 Fragment,然后在每个方法中初始化适当的字段并设置另一个(如果已定义)。这样,无论首先调用哪个,它都可以正常工作,而不会使菜单无效。

这基本上是它的样子

public class myFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
...
private ShareActionProvider shareActionProvider;
private Intent shareIntent;
...

onCreateOptionsMenu()

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.menu_my_fragment, menu);

    MenuItem menuItem = menu.findItem(R.id.action_share);
    shareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(menuItem);
    //in the case where onLoadFinished is called first, simply set the share intent here.
    if (null != shareIntent)
    {
        shareActionProvider.setShareIntent(shareIntent);
    }
}

onLoadFinished()

@Override
public void onLoadFinished(android.support.v4.content.Loader<Cursor> loader, Cursor data) {

    ... <get some data from cursor> ...

    shareIntent = new Intent(Intent.ACTION_SEND);
    shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
    shareIntent.setType("text/plain");
    shareIntent.putExtra(Intent.EXTRA_TEXT, getString(R.string.share_text)+data);

    //shareActionProvider may be null due to onLoadFinished called before onCreateOptionsMenu
    if (null != shareActionProvider)
    {
        shareActionProvider.setShareIntent(shareIntent);
    }
于 2016-03-08T04:58:46.057 回答
1

我需要根据加载程序的结果更改一些操作菜单项。什么方法可以解决这个问题?

那么,您的场景 #2 和 #3 应该非常适合您。到时间onCreateOptionsMenu()被调用时,您已经拥有了您的Cursor(或其他),Loader并且可以定制您在onCreateOptionsMenu().

关于场景#1,onCreateOptionsMenu()做最有可能的事情,如果你确定onLoadFinished()这是不正确的,我想打电话invalidateOptionsMenu()来强制另一个电话。onCreateOptionsMenu()

于 2012-09-25T18:44:06.407 回答
0

这种特殊方法避免了使整个菜单无效。

根据加载器结果的结果,为要控制的每个项目定义一个布尔标志和一个 MenuItem 变量:

假设您只想在 loader 返回任何成功时启用New操作:

private boolean mEnableNew = false;
private MenuItem mItemNew;

创建菜单时将菜单项保存到变量中,同时应用状态:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
  getMenuInflater().inflate(R.menu.manage_menu, menu);

  mItemNew = menu.findItem(R.id.itm__manage_menu__new);
  mItemNew.setEnabled(mEnableNew);

  return super.onCreateOptionsMenu(menu);
}

最后,根据 Loader 的结果获取新的设置,并启用禁用菜单项:

@Override
public void onLoadFinished(Loader<BI_Result> loader, Result result) {

    //--If onCreateOptionsMenu is not yet executed,it will use this boolean value when it does
    mEnableNew = result.isSuccess(); 

    //--If onCreateOptionsMenu has executed, we apply state here
    if (mItemNew != null) {
        mItemNew.setEnabled(mEnableNew);
    }
}
于 2012-12-29T14:17:21.397 回答