Android – 从FragmentsanimationActionBar图标的问题

我遇到了一些问题, 一直在我的应用程序的ActionBar中animation刷新图标。

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

在操作栏中,我显示一个静态的“刷新”图标。 随着每个片段加载,我用一个animation的“微调”图标取代这个。 加载完成后,我恢复到原始刷新图标。

问题是,这个animation只适用于原始片段(在这种情况下是FragA)。 当用户导航到FragB并select刷新图标时,会触发刷新,但animation不会发生。 类似地,如果后退button被按下以返回到FragA,则这现在遵循相同的模式,即刷新button在按下时不animation。

注意事项…

  1. 我在https://github.com/jfeinstein10/SlidingMenu使用ActionBarSherlock和SlidingMenu实现。 所以上面的活动实际上是一个SlidingFragmentActivity
  2. 这两个片段调用setHasOptionsMenu(true) – 我已经debugging通过这和onCreateOptionsMenu被正确调用每个。
  3. 对于这两个片段,图标都正确显示 – 当我浏览“默认”片段时,animation就不会发生。
  4. 我看到相同的行为,当使用SlidingMenu导航 – FragA加载,animation作品 – > SlidingMenu被用来导航到不同的片段…animation不工作 – >后退button到FragA …animation不起作用这里也是。
  5. 我使用FragmentTransaction.remove()add()而不是replace()因为我以前有replace()后退button问题 – 我正在使用兼容性库,我在这里读取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调用ie …

 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); 

在调用onCreateOptionsMenu时,将menu分配给容器的实例variables。

更新:

我注意到在这个领域还有一个奇怪的错误(我很高兴把它作为一个单独的问题添加进来,但是我在这里更新它,希望能够解决我原来的问题 – 我相信这两个都是由我如何从我的碎片configuration我的行动栏)。

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

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

Solutions Collecting From Web of "Android – 从FragmentsanimationActionBar图标的问题"

不要在其他地方改变菜单项

 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); 

如果每次都使用相同的animation对象,则可能需要重新设置animation,然后再次尝试运行。

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

  "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 < – >风景)。

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

您正在添加一个动作视图来添加animation。 如果你试图做其他的事情,比如改变菜单项的图标(即使它没有animation,只是为了看看它是否改变),而不是这样做的工作?

只在主要活动(我的意思是滑动片段活动)中调用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 slidingmenu库,我不添加或删除碎片,我总是replace他们和在创buildmenthod 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();