6

i'm using a ShareActionProvider, but i want to custom the icon (i want to change the color, because currently, it's white).

I'm using this code :

        mShareActionProvider = (ShareActionProvider) item.getActionProvider();
    Intent myIntent = new Intent(Intent.ACTION_SEND);
    myIntent.setType("text/plain");
    myIntent.putExtra(Intent.EXTRA_TEXT, str_share);
    mShareActionProvider.setShareIntent(myIntent);

The XML :

<item
  android:id="@+id/menu_item_share"
  android:showAsAction="ifRoom"
  android:title="@string/titlePartager"
  android:actionProviderClass="android.widget.ShareActionProvider"
  android:icon="@drawable/ic_share"/>

How can i change the icon (or color) ?

thx,

deveLost
  • 1,151
  • 2
  • 20
  • 47

3 Answers3

8

Edit / Short answer: if using AppCompat's ShareActionProvider, just provide a new actionModeShareDrawable in your theme definition.

<style name="MyTheme" parent="Theme.AppCompat">
    <item name="actionModeShareDrawable">@drawable/my_share_drawable</item>
</style>

If not using AppCompat, then this resource is defined for Lollipor or newer, but not for previous versions.


Below is answer for the native ShareActionProvider (which was the original scope of this question).

To change this image, you should change the value of actionModeShareDrawable for your app's theme. Take a look at the ShareActionProvider's onCreateActionView() method:

public View onCreateActionView() {
    // Create the view and set its data model.
    ...

    // Lookup and set the expand action icon.
    TypedValue outTypedValue = new TypedValue();
    mContext.getTheme().resolveAttribute(R.attr.actionModeShareDrawable, outTypedValue, true);
    Drawable drawable = mContext.getResources().getDrawable(outTypedValue.resourceId);
    ...  

Unfortunately this attribute is not public in the Android framework (though it is if using compatibility libraries, such as AppCompat or ActionBarSherlock). In that case, it's just a matter of overriding that value for the theme.

If you are using neither of these libraries, the only solution (that I know of) is to create a subclass of ShareActionProvider and reimplement the onCreateActionView() method. You can then use whatever drawable you want instead.

EDIT However this is further complicated by the fact that the implementation of onCreateActionView() uses other classes that are not public either. To avoid duplicating a lot of code, you can just change the icon via reflection, like this:

public class MyShareActionProvider extends ShareActionProvider
{
    private final Context mContext;

    public MyShareActionProvider(Context context)
    {
        super(context);
        mContext = context;
    }

    @Override
    public View onCreateActionView()
    {
        View view = super.onCreateActionView();
        if (view != null)
        {
            try
            {
                Drawable icon = ... // the drawable you want (you can use mContext to get it from resources)
                Method method = view.getClass().getMethod("setExpandActivityOverflowButtonDrawable", Drawable.class);
                method.invoke(view, icon);
            }
            catch (Exception e)
            {
                Log.e("MyShareActionProvider", "onCreateActionView", e);
            }
        }

        return view;
    }
}

As with any solutions that involve reflection, this may be brittle if the internal implementation of ShareActionProvider changes in the future.

matiash
  • 54,791
  • 16
  • 125
  • 154
  • mhhh, i don't understand how to reimplement the oncreateactionview, what's the initial code in this function ? – deveLost Jun 29 '14 at 09:08
  • @devLost The original code is at https://github.com/android/platform_frameworks_base/blob/master/core/java/android/widget/ShareActionProvider.java Are you _sure_ you're not using the `appcompat` library? Because if you did, it would be way easier, this approach involves duplicating a lot of framework code. – matiash Jun 29 '14 at 15:56
  • mhh, i tried to modify this code, to change the drawable, but i had many errors. I will try again. What will change if i import the appcompat library ? – deveLost Jun 29 '14 at 16:03
  • @deveLost Yes, because it uses other classes that are private to the framework too. You will have to duplicate those classes too :/ – matiash Jun 29 '14 at 16:11
  • @deveLost Edited my answer with a possibly better solution. – matiash Jun 29 '14 at 16:54
  • i tried that : mShareActionProvider = (MyShareActionProvider) item.getActionProvider(); Intent myIntent = new Intent(Intent.ACTION_SEND); myIntent.setType("text/plain"); myIntent.putExtra(Intent.EXTRA_TEXT, str_share); mShareActionProvider.setShareIntent(myIntent); but i've a nullpointerexception, i don't know where :/ – deveLost Jul 01 '14 at 18:49
  • @deveLost Strange, I used this in a test project with no problems at all. You did change the menu xml to use `com.your.package.name.MyShareActionProvider`, right? If you post the stack trace from logcat we might be able to diagnose it. – matiash Jul 01 '14 at 19:04
  • yes, i did it. Ok, i check again, and i share it here if i've the problem again. thx for help :) – deveLost Jul 01 '14 at 19:25
  • oh it's running, nice man ! (just a little mistake from myself) Thx a lot !! – deveLost Jul 01 '14 at 19:27
3

To change the icon for the ShareActionProvider you need to extend the AppCompat theme and set your custom icon to "actionModeShareDrawable":

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="actionModeShareDrawable">@drawable/ic_share</item>
</style>
nGL
  • 333
  • 3
  • 12
0

You can change background color by defining custom style, as:

<resources>
    <style name="MyTheme" parent="@android:style/Theme.Holo.Light">
        <item name="android:actionBarStyle">@style/MyActionBar</item>
    </style>

    <style name="MyActionBar" parent="@android:style/Widget.Holo.Light.ActionBar">
        <item name="android:background">ANY_HEX_COLOR_CODE</item>
    </style>
</resources>

Now you need to set "MyTheme" as theme for application / activity.

Karim Baidar
  • 677
  • 3
  • 10
  • I don't want to change the background color :/ – deveLost May 24 '14 at 16:49
  • the Sherlock theme uses the "actionModeShareDrawable" as found in theme.xml file. Try changing your theme to include the "actionModeShareDrawable" item directly. – Karim Baidar May 24 '14 at 16:53
  • sorry, i absolutely forgot to answer. I'm not using Sherlock, i'm using HOlo them, and that it doesn't work. – deveLost Jun 02 '14 at 14:58