11

我在我的应用程序的 ActionBar 中始终为“刷新”图标设置动画时遇到了一些问题。

我有一个容器 FragmentActivity,它在用户浏览应用程序时交换片段(从片段本身或从 SlidingMenu 选项)。所以当应用程序第一次加载时,我的 FragmentContainer 添加了 FragA。用户可以从 FragA 导航到 FragB,然后将其换入。

在操作栏中,我显示一个静态的“刷新”图标。随着每个片段的加载,我将其替换为动画“微调器”图标。加载完成后,我恢复到原来的刷新图标。

问题是,这个动画只适用于原始片段(FragA,在这种情况下)。当用户导航到 FragB 并选择刷新图标时,会触发刷新,但动画永远不会发生。类似地,如果按下后退按钮返回到 FragA,这将遵循相同的模式,即刷新按钮在按下时不会动画。

注意事项...

  1. 我在https://github.com/jfeinstein10/SlidingMenu使用 ActionBarSherlock 和 SlidingMenu 实现。所以上面的活动实际上是一个SlidingFragmentActivity.
  2. 两个 Fragments 调用setHasOptionsMenu(true)- 我已经通过这个进行了调试,并且onCreateOptionsMenu每个都被正确调用。
  3. 两个片段的图标都正确显示-当我离开“默认”片段时,动画没有发生。
  4. 我在使用 SlidingMenu 导航时看到相同的行为 - FragA 加载,动画工作 -> SlidingMenu 用于导航到不同的片段...动画不起作用 -> 返回按钮到 FragA...动画不起作用在这里。
  5. 我正在使用FragmentTransaction.remove()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);

调用时将wheremenu分配给容器的实例变量onCreateOptionsMenu

更新:

我注意到这个领域的另一个奇怪的错误(我很高兴将它作为一个单独的问题添加,但我在这里更新它,希望它能够阐明我原来的问题 - 我相信两者都是由我如何从我的片段配置我的操作栏)。

当我第一次加载片段时,我会显示 1 个静态刷新图标。如果我旋转屏幕...会出现另一个刷新图标...当我将屏幕旋转回来时,会出现第三个刷新图标!

更奇怪的是,单击后退按钮会依次删除每个附加图标,然后最终(第四次单击)返回到前一个屏幕。

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()
}

所以现在你可以从你的框架打电话

((YourActivity)getActivity()).setRefreshing(true);
((YourActivity)getActivity()).setRefreshing(false);
于 2013-04-02T16:29:12.973 回答
1

您正在添加一个动作视图来添加动画。如果您尝试做其他事情,例如更改菜单项的图标(即使它没有动画,只是为了查看它是否更改),那会起作用吗?

于 2013-04-04T08:39:33.783 回答
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."

我可以解释一下,当你改变方向时(Potrait<->landscape)。

当方向改变时重新启动一个活动。我猜您的代码在重新启动之前没有保存所需的信息。您可以通过自己处理特定的配置更改(即:方向更改)来停止此默认行为。一个很好的教程在这里:处理运行时更改

于 2013-04-04T04:13:48.557 回答
1

如果您每次都使用相同的 Animation 对象,则可能需要在尝试再次运行之前重置动画。

尝试在对 startAnimation() 的调用上方添加 rotation.reset()。

于 2013-03-28T20:30:26.577 回答
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 滑动菜单库,我没有添加或删除片段,我总是替换它们并在 oncreate menthod iam 中像这样使用

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 回答