Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - problems animating ActionBar icon from Fragments

I'm having some problems consistently animating a 'refresh' icon in the ActionBar of my app.

I have a container FragmentActivity which swaps fragments in and out as the user navigates through the app (either from within the fragment itself or from a SlidingMenu option). So when the app first loads, my FragmentContainer adds FragA. From FragA the user can navigate to FragB which is then swapped in.

In the action bar I display a static 'refresh' icon. As each Fragment loads, I replace this with an animated 'spinner' icon. When the load completes, I revert to the original refresh icon.

Problem is, this animation only works for the original fragment (FragA, in this case). When the user navigates to FragB and selects the refresh icon, the refresh is triggered, but the animation never happens. Similarly, if the back button is pressed to return to FragA, this now follows the same pattern i.e. the refresh button does not animate when pressed.

Things to note...

  1. I'm using ActionBarSherlock and the SlidingMenu implementation at https://github.com/jfeinstein10/SlidingMenu. So the above activity is actually a SlidingFragmentActivity.
  2. Both Fragments call setHasOptionsMenu(true) - I've debugged through this and onCreateOptionsMenu is being correctly called for each.
  3. The icons are being correctly displayed for both Fragments - the animation is just not happening when I navigate off the 'default' fragment.
  4. I see the same behaviour when using the SlidingMenu to navigate - FragA loads, animation works -> SlidingMenu is used to navigate to a different fragment... animation doesn't work -> Back button to FragA... animation doesn't work here either.
  5. I'm using FragmentTransaction.remove() and add() rather than replace() as I have previously had back-button issues with replace() - I am using the compatibility lib and I read on here that the replace implementation is a bit buggy - and not using it certainly fixed the issues I was seeing.

Code snippets below:

My code to load the original fragment is....

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

To 'swap' FragB for 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();
}

This method is declared in the container activity and is called from FragA i.e....

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

The code to spin the icon is called from the new Fragment as it starts to load. Its something like...

    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 is assigned to an instance variable of the container when onCreateOptionsMenu is called.

Update:

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.

like image 906
Neil Avatar asked Mar 25 '13 20:03

Neil


People also ask

How to remove Action bar from fragment in Android?

If you want to hide Action Bar from the entire application (from all Activities and fragments), then you can use this method. Just go to res -> values -> styles. xml and change the base application to “Theme. AppCompat.

How to Hide actionBar in Android Kotlin?

ActionBar actionBar = getActionBar(); actionBar. hide();

Can add Toolbar to fragment in Android?

Though you can add a Toolbar anywhere within your fragment's view hierarchy, you should generally keep it at the top of the screen. To use the Toolbar in your fragment, provide an ID and obtain a reference to it in your fragment, as you would with any other view.


3 Answers

Never chang menu items somewhere except

onPrepareOtionsMenu(){
}

you should something like this.

in your activity:

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

So now you can call from your frament

((YourActivity)getActivity()).setRefreshing(true);
((YourActivity)getActivity()).setRefreshing(false);
like image 88
Artem Zelinskiy Avatar answered Nov 15 '22 19:11

Artem Zelinskiy


If you are using the same Animation object each time, you may need to reset your animation before attempting to run it again.

Try adding rotation.reset() above your call to startAnimation().

like image 22
megabits Avatar answered Nov 15 '22 20:11

megabits


    "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."

I can give Explanation to this ,When ever you change orientation (Potrait<->landscape).

An activity is restarted when the orientation changes. I'm guessing your code isn't saving needed information before this restart occurs. You can stop this default behavior by handling specific configuration changes yourself (ie: orientation change). A good tutorial on doing this is located here: Handling Runtime Changes

like image 22
Viswanath Lekshmanan Avatar answered Nov 15 '22 19:11

Viswanath Lekshmanan