7

I'm attempting to implement a refresh button in my app to allow a user to manually re-sync to a web server. The code works, but I'm having trouble figuring out the action views (at least, I think that's what I'm supposed to be using).

My menu item is here:

<item
    android:id="@+id/main_menu_refresh"
    android:enabled="true"
    android:icon="@drawable/refresh"
    android:orderInCategory="1"
    android:showAsAction="ifRoom"
    android:title="@string/refresh" 
    android:actionViewClass="android.widget.ProgressBar">
</item>

The problem is, it always shows the ProgressBar. I wondered if it worked like the search widget (the only example I really see online) and added the collapseActionView tag to the showAsAction and that prevented it from showing up immediately. However, when I click the refresh button, the icon disappears (good), but so does the Title in the action bar, and the ProgressBar appears on the left side of the window where the title used to be. Also not what I wanted.

As something of a last ditch effort, I attempted to add this to my code, and remove the actionViewClass from the XML:

MenuItem refresh = (MenuItem)findViewById(R.id.main_menu_refresh);
Log.w("MyApp", "Have Menu");
ProgressBar pb = new ProgressBar(ReadingList.this);
refresh.setActionView(pb);

That didn't work either, giving me a null pointer error on setActionView.

I need a solution that I can call from any function (there is an auto-sync period at the beginning I would like the ProgressBar to display during as well), and be able to return it to it's static icon after.

I tried reading through this question, but I am having trouble understanding what the answer means. I feel like I was trying to do just what it says, but I guess not. Any assistance is much appreciated.

Edit: For sastraxi's suggestion.

public class IconSwitcher extends LinearLayout{



public IconSwitcher(Context context) {
    super(context);

    ProgressBar pb = new ProgressBar(context);
    ImageView iv = new ImageView(context);

    addView(iv);
    addView(pb);
}
}

This is my class thus far. However, when I try and reference it with:

MenuItem refresh = (MenuItem)findViewById(R.id.main_menu_refresh);
IconSwitcher ic = (IconSwitcher) refresh.getActionView();

I get a null pointer error. on creating the IconSwitcher. The button XML is as follows:

<item
    android:id="@+id/main_menu_refresh"
    android:enabled="true"
    android:icon="@drawable/refresh"
    android:orderInCategory="1"
    android:showAsAction="ifRoom"
    android:title="@string/refresh" 
    android:actionViewClass="IconSwitcher">
</item>

I'm just having a difficult time on referencing that IconSwitcher View.

Edit 2: I'm appearantly having trouble referencing the Menu Item at all.

MenuItem refresh = (MenuItem)findViewById(R.id.main_menu_refresh);
refresh.setVisible(false);

Also gives me a null pointer when I try and set the visibility. What is wrong with my references?

Community
  • 1
  • 1
The Holo Dev
  • 1,016
  • 3
  • 12
  • 22
  • This is not failing at setActionView but at the point where you're doing (MenuItem)findViewById(R.id.main_menu_refresh). It apparently is a ClassCastException to cast ActionItemView to MenuItem. – Namratha Jan 29 '13 at 10:57
  • I figured it out. I found this previous [SO](http://stackoverflow.com/questions/7142722/replacing-an-actionbar-menu-item-icon-with-an-indeterminate-progressbar) question. From there, I found code Google wrote on doing this [here](http://developer.android.com/resources/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelperHoneycomb.html). It was basically copy and paste at that point, and works perfectly. – The Holo Dev Mar 30 '12 at 17:23

3 Answers3

0

Try to use:

<item
    android:id="@+id/main_menu_refresh"
    android:enabled="true"
    android:icon="@drawable/refresh"
    android:orderInCategory="1"
    android:title="@string/refresh"
    app:showAsAction="ifRoom"
    app:actionViewClass="android.widget.ProgressBar">
</item>

Note this two lines:

    app:showAsAction="ifRoom"
    app:actionViewClass="android.widget.ProgressBar"
Rafa0809
  • 1,733
  • 21
  • 24
0

Did you try to fetch your menu item like this?

MenuItem item = getToolbar().getMenu().findItem(Menu.FIRST);
Alen Siljak
  • 2,482
  • 2
  • 24
  • 29
0

Instead of setting your action view class to a ProgressBar, set it to a custom LinearLayout class, as such:

class MyViewItem extends LinearLayout

Add a ProgressBar and an ImageView as children in its constructor with addView, and set these childrens' visibilities as either GONE or VISIBLE when your code requires it.

sastraxi
  • 1,330
  • 11
  • 21
  • I'm having trouble understanding. Can you give me a little more detail on this custom class? I added more to the main post to show what I'm having trouble with. – The Holo Dev Mar 30 '12 at 02:20
  • You need to use the fully-qualified name in the XML, e.g. `com.mydomain.mypackage.IconSwitcher`, rather than just `IconSwitcher`. Try that, see if things start working. – sastraxi Mar 30 '12 at 02:30
  • Nope, I still have a null pointer error. It's also definitely on the `IconSwitcher ic = (IconSwitcher) refresh.getActionView();` line. If I comment that line out, I don't get any errors, but I obviously don't get a dynamic button, just the static icon. Do I need to declare the IconSwitcher in the manifest in any way? – The Holo Dev Mar 30 '12 at 02:48
  • Can you try using `setActionView(new IconSwitcher(...))` instead of setting the action view class in the XML? I'm guessing that android internally uses `MenuItemImpl`, which should return a non-null if you set it that way. Also, you can just keep a reference to it outright... – sastraxi Mar 30 '12 at 05:24
  • Hmm, I thought I was keeping a reference to it, but turns out I was calling on the reference in a different thread before I actually got it. I'm starting to be able to manipulate it. At this point, I think I'll have to menu items. One that is the refresh icon. When it's pressed, I'll put a progress bar in it's place, rather than try and change the icon itself. When done, I'll switch them back. – The Holo Dev Mar 30 '12 at 06:20