11

アプリの ActionBar で「更新」アイコンを一貫してアニメーション化する際に問題が発生しています。

ユーザーがアプリをナビゲートするときにフラグメントをスワップインおよびスワップアウトするコンテナー FragmentActivity があります (フラグメント自体または SlidingMenu オプションから)。したがって、アプリが最初に読み込まれると、FragmentContainer は FragA を追加します。ユーザーは FragA から FragB に移動でき、FragB はスワップインされます。

アクション バーに静的な「更新」アイコンを表示します。各 Fragment が読み込まれるたびに、これをアニメーション化された「スピナー」アイコンに置き換えます。ロードが完了すると、元の更新アイコンに戻ります。

問題は、このアニメーションが元のフラグメント (この場合は FragA) に対してのみ機能することです。ユーザーが FragB に移動して更新アイコンを選択すると、更新がトリガーされますが、アニメーションは発生しません。同様に、戻るボタンを押して FragA に戻る場合、これは同じパターンに従います。つまり、更新ボタンを押してもアニメーションしません。

注意事項...

  1. https://github.com/jfeinstein10/SlidingMenuで ActionBarSherlock と SlidingMenu 実装を使用しています。したがって、上記のアクティビティは実際にはSlidingFragmentActivity.
  2. 両方のフラグメント呼び出しsetHasOptionsMenu(true)- 私はこれをデバッグしonCreateOptionsMenu、それぞれに対して正しく呼び出されています。
  3. 両方のフラグメントのアイコンが正しく表示されています。「デフォルト」のフラグメントから移動すると、アニメーションが発生しません。
  4. SlidingMenu を使用してナビゲートすると同じ動作が見られます - FragA がロードされ、アニメーションが動作します -> SlidingMenu を使用して別のフラグメントに移動します... アニメーションが機能しません -> FragA に戻るボタン... アニメーションが機能しませんここでも。
  5. 以前に戻るボタンの問題があったのではなく、FragmentTransaction.remove()andを使用しています-互換性ライブラリを使用していますが、実装に少しバグがあることをここで読みました-使用しないことで、私が見ていた問題が確実に修正されました.add()replace()replace()replace

以下のコード スニペット:

元のフラグメントをロードする私のコードは....

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.content_frame, new FragA());
ft.addToBackStack(null);
ft.commit();

FragB を FragA に「スワップ」するには....

public void switchContent(PysoBaseFragment fragment) {
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.remove(existingFragment);
    ft.add(R.id.content_frame, fragment);
    ft.addToBackStack(null);
    ft.commit();
}

このメソッドはコンテナー アクティビティで宣言され、FragA から呼び出されます。

getFragmentContainer().switchContent(new FragB());

アイコンを回転させるコードは、新しい Fragment の読み込み開始時に呼び出されます。そのようなもの...

    ImageView spinnerActionView = (ImageView) inflater.inflate(R.layout.refresh_action_view, null);
    Animation rotation = AnimationUtils.loadAnimation(this, R.anim.rotate_animation);
    rotation.setRepeatCount(Animation.INFINITE);
    spinnerActionView.startAnimation(rotation);
    menuItemRefresh = menu.findItem(R.id.menu_refresh);
    menuItemRefresh.setActionView(spinnerActionView);

Whereが呼び出されるとmenu、コンテナのインスタンス変数に割り当てられます。onCreateOptionsMenu

アップデート:

この分野で別の奇妙なバグに気づきました(これを別の質問として追加できてうれしいですが、元の問題に光を当てることを期待してここで更新しています-両方が原因であると信じていますフラグメントからアクションバーをどのように構成したか)。

フラグメントを初めてロードすると、1 つの静的更新アイコンが表示されます。画面を回転すると...別の更新アイコンが表示されます...画面を元に回転すると、3番目の更新アイコンが表示されます!

それでも見知らぬ人は、戻るボタンをクリックすると、追加の各アイコンが順番に削除され、最後に (4 回目のクリックで) 前の画面に戻ります。

4

5 に答える 5

5

以外の場所でメニュー項目を変更しないでください

onPrepareOtionsMenu(){
}

あなたはこのようなものでなければなりません。

あなたの活動で:

boolean mIsRefreshing =false;

public boolean onPrepareOptionsMenu(Menu menu) {
if(mIsRefreshing){
        final MenuItem menuItemRefresh = menu.findItem(R.id.menu_refresh);
    menuItemRefresh.setActionView(spinnerActionView);
}
        return true;
    }

public void setRefreshing(boolean refreshing){
mIsRefreshing = refreshing;
invalidateOptionsMenu();  //supportInvelidateOptionsMenu()
}

これで、frament から呼び出すことができます

((YourActivity)getActivity()).setRefreshing(true);
((YourActivity)getActivity()).setRefreshing(false);
于 2013-04-02T16:29:12.973 に答える
1
    "I've noticed another weird bug in this area (I'm happy to add this as a separate question, but I'm updating it here in the hope that it will shed some light on my original problem - I believe both are caused by how I have configured my action-bar from my Fragments).   
    When I first load a fragment I have 1 static refresh icon displayed. If I rotate the screen... another refresh icon appears... when I rotate the screen back, a 3rd refresh icon appears! 
    Stranger still, clicking the back-button removes each additional icon in turn, before finally (on the 4th click) returning to the previous screen."

これについては、向きを変えるたびに説明できます(ポートレイト<->ランドスケープ)。

向きが変わるとアクティビティが再開されます。この再起動が発生する前に、コードが必要な情報を保存していないと思います。特定の構成変更 (つまり、向きの変更) を自分で処理することにより、このデフォルトの動作を停止できます。これを行うための優れたチュートリアルがここにあります: ランタイム変更の処理

于 2013-04-04T04:13:48.557 に答える
1

メイン アクティビティでのみ onCreateOptionsMenu() を呼び出します (スライド フラグメント アクティビティを意味します)。すべてのフラグメントから onCreateOptionsMenu() を呼び出す必要はありません。以下にサンプル スニペットを示します。

Call from fragment (whenerver loading starts and end)

    yourSlidingFragmnetActivity.refresh = true/false; (u can have this logic of your own)
    getActivity().supportInvalidateOptionsMenu();


    @Override
        public boolean onCreateOptionsMenu(Menu menu) {


            menu.add(BaseListActivity.DEFAULT_GROUP_ID, BaseListActivity.MENU_ITEM_RELOAD_LIST, BaseListActivity.DEFAULT_ORDER,
                    "Refresh").setIcon(R.drawable.ic_menu_refresh_new)
                    .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
            return true;
        }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {

            if (item.getItemId() == BaseListActivity.MENU_ITEM_RELOAD_LIST) {
                item.setActionView(R.layout.progressbar_layout);
                item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
                return true;
            }
            return true;
        }

        public static boolean refresh = false;

        @Override
        public boolean onPrepareOptionsMenu(Menu menu) {
            MenuItem item = menu.getItem(0);
            if (refresh) {
                item.setActionView(R.layout.progressbar_layout);
            } else {
                item.setIcon(R.drawable.ic_menu_refresh_new);
            }
            return true;
        }

        R.layout.progressbar_layout:
        <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:addStatesFromChildren="true"
                      android:focusable="true"
                      android:paddingLeft="4dp"
                      android:paddingRight="4dp"
                      android:gravity="center"
                      style="?attr/actionButtonStyle">
        <ProgressBar
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:focusable="true"
                    style="@android:style/Widget.ProgressBar.Small"/>
        </LinearLayout>

私は jfeinstein10 slidemenu lib も使用しています。フラグメントを追加または削除していません。常にそれらを置き換えており、oncreate メソッドではこのように使用しています

private Fragment mContent;
if(mContent == null){
mContent = new SampleFragment();
}
// set the Above View
    setContentView(R.layout.content_frame);
                getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.content_frame,mContent)
                .commit();      
于 2013-04-04T09:44:04.043 に答える
1

アニメーションを追加するアクション ビューを追加しています。メニュー項目のアイコンを変更する (アニメーション化されていなくても、変更されるかどうかを確認するためだけに) など、何か他のことをしようとすると、代わりに機能しますか?

于 2013-04-04T08:39:33.783 に答える
1

毎回同じ Animation オブジェクトを使用している場合は、再度実行する前にアニメーションをリセットする必要がある場合があります。

startAnimation() の呼び出しの上に、rotation.reset() を追加してみてください。

于 2013-03-28T20:30:26.577 に答える