Android Custom Icon ShareActionProvider?
Asked Answered
N

3

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,

Nahamas answered 24/5, 2014 at 14:28 Comment(0)
N
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.

Nide answered 29/6, 2014 at 0:6 Comment(9)
mhhh, i don't understand how to reimplement the oncreateactionview, what's the initial code in this function ?Nahamas
@devLost The original code is at github.com/android/platform_frameworks_base/blob/master/core/… 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.Nide
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 ?Nahamas
@Nahamas Yes, because it uses other classes that are private to the framework too. You will have to duplicate those classes too :/Nide
@Nahamas Edited my answer with a possibly better solution.Nide
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 :/Nahamas
@Nahamas 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.Nide
yes, i did it. Ok, i check again, and i share it here if i've the problem again. thx for help :)Nahamas
oh it's running, nice man ! (just a little mistake from myself) Thx a lot !!Nahamas
S
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>
Sewerage answered 23/2, 2015 at 16:0 Comment(0)
H
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.

Hammering answered 24/5, 2014 at 16:47 Comment(3)
I don't want to change the background color :/Nahamas
the Sherlock theme uses the "actionModeShareDrawable" as found in theme.xml file. Try changing your theme to include the "actionModeShareDrawable" item directly. <style name="Theme.MyApp" parent="Theme.Sherlock.Light"> <item name="actionModeShareDrawable">@drawable/ic_action_share</item> </style>Hammering
sorry, i absolutely forgot to answer. I'm not using Sherlock, i'm using HOlo them, and that it doesn't work.Nahamas

© 2022 - 2024 — McMap. All rights reserved.