ShareActionProvider not clickable and not rendering properly on first render
Asked Answered
C

4

11

I have a ShareActionProvider together with some other options in my ActionBar. It seems however that the ShareActionProvider has problems rendering properly when first rendered in portrait mode and it is not clickable on the first render. An orientation change re-renders the screen and then all the options that are supposed to be visible are visible and when rotating back the ActionBar re-renders again but this time it is rendering properly in portrait mode as well.

I've attached an image that describes the situation:

  1. The Share option is not properly rendered, it should have an icon next to it and if it doesn't fit the layout, it should become a 3-dot menu.

  2. After orientation all options are visible as expected.

  3. Rotating back to portrait re-renders the ActionBar and now the 3-dot menu appear as it should and it is clickable.

Any ideas on what's going on here?

ActionBar description

This is my XML:

    <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/item_delete"
        android:icon="@android:drawable/ic_menu_delete"
        android:showAsAction="ifRoom|withText"
        android:title="Delete"
        android:visible="false"/>
    <item
        android:id="@+id/item_edit"
        android:icon="@android:drawable/ic_menu_edit"
        android:showAsAction="ifRoom|withText"
        android:title="Edit"
        android:visible="false"/>
    <item
        android:id="@+id/item_share"
        android:actionProviderClass="android.widget.ShareActionProvider"
        android:showAsAction="ifRoom|withText"
        android:title="Share"
        android:visible="false"/>
    <item
        android:id="@+id/item_save"
        android:icon="@android:drawable/ic_menu_save"
        android:showAsAction="ifRoom|withText"
        android:title="Save"
        android:visible="false"/>
    <item
        android:id="@+id/menu_search"
        android:actionViewClass="android.widget.SearchView"
        android:icon="@android:drawable/ic_menu_search"
        android:showAsAction="ifRoom"
        android:title="@string/menu_search"
        android:visible="false"/>

</menu>

and this is how I handle the options menu in a Fragment:

 /**
 * Hook into the OptionsMenu and add an Edit, Delete and Share option.
 */
@Override
public void onPrepareOptionsMenu(Menu menu) {
    MenuItem deleteItem = menu.findItem(R.id.item_delete);
    deleteItem.setVisible(true);

    MenuItem editItem = menu.findItem(R.id.item_edit);
    editItem.setVisible(true);

    MenuItem shareItem = menu.findItem(R.id.item_share);
    shareItem.setVisible(true);
    shareActionProvider = (ShareActionProvider) shareItem.getActionProvider();
    shareActionProvider.setShareIntent(getShareIntent());

    super.onPrepareOptionsMenu(menu);
}

/**
 * Builds an intent that takes the path for the image and passes it to 
 * the sharing mechanism as a stream built on the URI of the image path.
 * @return the intent to share the image as a stream
 */
private Intent getShareIntent()
{
    Intent shareIntent = new Intent();
    shareIntent.setAction(Intent.ACTION_SEND);
    shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + receipt.getPhoto()));
    shareIntent.setType("image/jpeg");
    return shareIntent;
}
Cogan answered 23/8, 2012 at 7:58 Comment(0)
S
30

That's because you have to add an intent to the ShareActionPRovider right after you inflate the menu, on onCreateOptionsMenu.

If you do that only in onPrepareOptionsMenu, you'll have to manually call invalidateOptionsMenu() to trigger an ActionBar update (as the chosen answer tells you to). But that's not the way to do it.

It works fine when the configuration changes, because onPrepareOptionsMenu() is called, and then your share button will work, since it now has an Intent.

To fix that, just do something like this:

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    getSupportMenuInflater().inflate(R.menu.YOUR_MENU_XML, menu);

    ShareActionProvider provider = (ShareActionProvider) menu.findItem(R.id.menu_share).getActionProvider();

    if (provider != null) {
        Intent shareIntent = new Intent();
        shareIntent.setAction(Intent.ACTION_SEND);
        shareIntent.putExtra(Intent.EXTRA_TEXT, YOUR_TEXT);
        shareIntent.setType("text/plain");
        provider.setShareIntent(shareIntent);
    }

    return true;
}

This way, the ShareActionProvider will have an Intent from the beginning, and will work as expected.

Stickler answered 14/5, 2013 at 21:42 Comment(1)
Very interesting! I will look into this as soon as I get some spare time. Thanks!Cogan
C
1

So it seems that calling "getActivity().invalidateOptionsMenu()" in onCreateView in the Fragment makes the menu re-render as it should. It should render properly in the first run though, invalidating the menu without making changes to it doesn't feel like a proper solution.

Cogan answered 23/8, 2012 at 8:32 Comment(0)
S
1

It seams like platform bug. you can check this http://code.google.com/p/android/issues/detail?id=25467 for more information.

Sudan answered 26/12, 2012 at 3:57 Comment(0)
A
1

I don't think it's a bug. It's because your title changed. It was shorter ("Details" instead of "ReceiptDetail") originally, and so the system must have thought there was more room to show more action items.

Also the width of the ShareActionProvider is dynamic (it can be up to more than 2 times the normal width).

To test a thing or two, I would propose you move the share action item up to the first position, remove your temporary workaround, and see if it still occurs. You could also remove the share action item and use 3 or more conventional action items as a test.

Assignation answered 26/12, 2012 at 22:4 Comment(1)
Thanks, will look into this when I get back from my vacation.Cogan

© 2022 - 2024 — McMap. All rights reserved.