Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Custom Icon ShareActionProvider?

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,

like image 246
deveLost Avatar asked May 24 '14 14:05

deveLost


2 Answers

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.

like image 192
matiash Avatar answered Nov 14 '22 17:11

matiash


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>
like image 42
nGL Avatar answered Nov 14 '22 16:11

nGL