7

AsynctaskLoaderアクティビティの から開始されるOnCreate()と、その作業が終了し、onLoaderFinished() アクション バー メニューが拡張される前、つまり が呼び出される前onCreateOptionsMenu()に呼び出されます。

ローダーの結果に応じて、いくつかのアクション メニュー項目を変更する必要があります。これを解決するにはどのようなアプローチが考えられますか?

更新: これは向きの変更時に発生します。私はデバッガでこのシーケンスを観察しています:

  1. アプリケーションの開始: onCreate()-> onCreateOptionsMenu()->onLoadFinished()
  2. 横向きに回転: onCreate()-> onLoadFinished()->onCreateOptionsMenu()
  3. 縦向きに戻す: onCreate()-> onLoadFinished()->onCreateOptionsMenu()
4

3 に答える 3

2

を呼び出そうとしたときに、で初期化されている shareActionProvider に依存していたshareActionProvider.setShareIntent()のと同じシナリオに遭遇しました。onLoadFinished()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

この特定のアプローチは、メニュー全体の無効化を回避します。

ローダーの結果に基づいて制御する項目ごとに、1 つのブール値フラグと 1 つの 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);
}

最後に、ローダーの結果に基づいて新しい設定を取得し、無効化メニュー項目を有効にします。

@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 に答える