加载程序在Activity的onCreateOptionsMenu之前调用onLoadFinished

当一个AsynctaskLoader从Activity的OnCreate()启动时,它完成它的工作,并且在操作栏菜单被充满之前调用onLoaderFinished() ,这是在onCreateOptionsMenu()被调用之前。

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

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

  • 应用程序开始: onCreate() - > onCreateOptionsMenu() - > onLoadFinished()
  • 旋转到横向: onCreate() - > onLoadFinished() - > onCreateOptionsMenu()
  • 旋转回肖像: onCreate() - > onLoadFinished() - > onCreateOptionsMenu()

  • 我跑进试图打电话的时候,同样的场景shareActionProvider.setShareIntent()onLoadFinished()这是依赖于shareActionProvider在被initalized 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);
        }
    

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

    那么你的场景#2和#3对你来说应该是完美的。 到onCreateOptionsMenu()被调用时,你可以从你的Loader获得你的Cursor (或其他),并且可以定制你在onCreateOptionsMenu()做的事情。

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


    这种特殊的方法避免了整个菜单失效。

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

    假设您只想在加载程序返回任何成功时启用“新建”操作:

    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);
        }
    }
    
    链接地址: http://www.djcxy.com/p/11207.html

    上一篇: Loader calls onLoadFinished before Activity's onCreateOptionsMenu

    下一篇: Read an environment variable from applicationContext.xml