AppCompat ShareActionProvider icon is too big compared to other icons
Asked Answered
M

3

13

I changed the ActionBarSherlock to AppCompat v7. I already did all the changes that are needed to make it work, but something weird is happening with share icon (which is using ShareActionProvider). The share icon is too big compared to other icons. I also use the support library for my search, and its size is correct. The problem is just with the share icon.

enter image description here

my_menu.xml:

    <menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:moblee="http://schemas.android.com/apk/res-auto" >
    <item
        android:id="@+id/menu_share"
        android:padding="10dp"
        android:title="@string/menu_share"
        moblee:actionProviderClass="android.support.v7.widget.ShareActionProvider"
        moblee:showAsAction="always"/>
    <item
        android:id="@+id/menu_search"
        android:title="@string/menu_search"
        moblee:actionViewClass="android.support.v7.widget.SearchView"
        moblee:showAsAction="always"/>
</menu>

fragment:

public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.my_menu, menu);
    MenuItem item = menu.findItem(R.id.menu_share);
    ShareActionProvider shareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(item);
    shareActionProvider.setShareIntent(getDefaultShareIntent());
}

styles.xml

<style name="Theme.Custom" parent="Theme.AppCompat.Light.DarkActionBar">

        <item name="colorPrimary">@color/main_bar</item>
        <item name="colorPrimaryDark">@color/main_bar</item>
        <item name="actionBarItemBackground">@drawable/selectable_background_custom</item>
        <item name="selectableItemBackground">@drawable/selectable_background_custom</item>

        <item name="android:windowBackground">@color/background</item>

        <item name="android:popupMenuStyle">@style/PopupMenu.Custom</item>
        <item name="android:dropDownListViewStyle">@style/DropDownListView.Custom</item>
        <item name="android:actionDropDownStyle">@style/DropDownNav.Custom</item>
        <item name="android:actionModeBackground">@drawable/cab_background_top_custom</item>
        <item name="android:actionModeSplitBackground">@drawable/cab_background_bottom_custom</item>
        <item name="android:actionModeCloseButtonStyle">@style/ActionButton.CloseMode.Custom</item>

        <item name="vpiTabPageIndicatorStyle">@style/VpiTabPageIndicator.Custom</item>
        <item name="android:editTextBackground">@drawable/edit_text_holo_light</item>
        <item name="android:listChoiceBackgroundIndicator">@drawable/list_selector_holo_light</item>
        <item name="android:activatedBackgroundIndicator">@drawable/activated_background_holo_light</item>
        <item name="android:fastScrollThumbDrawable">@drawable/fastscroll_thumb_holo</item>
        <item name="android:listViewStyle">@style/ListViewCustom</item>
        <item name="android:gridViewStyle">@style/GridViewCustom</item>
        <item name="android:textViewStyle">@style/TextViewCustom</item>
        <item name="android:checkboxStyle">@style/CheckBoxCustom</item>
    </style>

    <style name="PopupMenu.Custom" parent="@style/Widget.AppCompat.ListPopupWindow">
        <item name="android:popupBackground">@drawable/menu_dropdown_panel_custom</item>
    </style>

    <style name="DropDownListView.Custom" parent="@style/Widget.AppCompat.ListView.DropDown">
        <item name="android:listSelector">@drawable/selectable_background_custom</item>
    </style>

    <style name="Theme.Custom.Widget" parent="@style/Theme.AppCompat">
        <item name="android:popupMenuStyle">@style/PopupMenu.Custom</item>
        <item name="android:dropDownListViewStyle">@style/DropDownListView.Custom</item>
    </style>
Myrtismyrtle answered 17/6, 2015 at 19:50 Comment(0)
M
5

The solution I ended up using is not use ShareContentProvider anymore, instead i'm using Intent.createChooser(). It was pretty simple to do these changes and it opens the new share dialog, as shown below:

share icon in action bar:

enter image description here

Dialog:

enter image description here

menu.xml

<item
    android:id="@+id/menu_share"
    android:checkable="true"
    android:icon="@drawable/ic_menu_share"
    myapp:showAsAction="always"
    android:title="@string/menu_share"/>

Fragment class:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int itemId = item.getItemId();
    if (itemId == R.id.menu_share) {
        showShareDialog();
    }
        return super.onOptionsItemSelected(item);
}

private void showShareDialog(String message) {
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_SEND);
    intent.setType("text/plain");

    intent.putExtra(Intent.EXTRA_SUBJECT, mTitle);
    intent.putExtra(Intent.EXTRA_TEXT, mMessage);

    startActivity(Intent.createChooser(intent, getString(R.string.menu_share)));
}
Myrtismyrtle answered 14/1, 2016 at 19:7 Comment(0)
G
13

Icons in material design are 24dp x 24dp, as properly reflected by the SearchView. However, ShareActionProvider has not yet been updated to material design by default.

You can set actionModeShareDrawable in your theme to set the share icon in the ShareActionProvider:

<item name="actionModeShareDrawable">@drawable/share_icon</item>

Note that ShareActionProvider is not found anywhere in the material design guidelines and with Android M's Direct Share capability (which requires you use a standard share intent at this time), it is unclear on whether the ShareActionProvider is a suggested pattern any more.

Gunman answered 17/6, 2015 at 20:21 Comment(3)
Thanks for the answer, it did help, but the solution didn't work. I setted a custom share icon, but it continued too big. I then created a new custom share icon with transparent borders. But actually, my final solution was create a new share, using Intent.createChooser().Myrtismyrtle
Thanks Ian. Somebody should really update developer.android.com/training/sharing/ . There's no mention of Direct Share there.Scope
@Gunman - any ideas? #34995778Dichroic
M
5

The solution I ended up using is not use ShareContentProvider anymore, instead i'm using Intent.createChooser(). It was pretty simple to do these changes and it opens the new share dialog, as shown below:

share icon in action bar:

enter image description here

Dialog:

enter image description here

menu.xml

<item
    android:id="@+id/menu_share"
    android:checkable="true"
    android:icon="@drawable/ic_menu_share"
    myapp:showAsAction="always"
    android:title="@string/menu_share"/>

Fragment class:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int itemId = item.getItemId();
    if (itemId == R.id.menu_share) {
        showShareDialog();
    }
        return super.onOptionsItemSelected(item);
}

private void showShareDialog(String message) {
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_SEND);
    intent.setType("text/plain");

    intent.putExtra(Intent.EXTRA_SUBJECT, mTitle);
    intent.putExtra(Intent.EXTRA_TEXT, mMessage);

    startActivity(Intent.createChooser(intent, getString(R.string.menu_share)));
}
Myrtismyrtle answered 14/1, 2016 at 19:7 Comment(0)
E
3

The only way I found was to create my own layout for activity chooser view. I went to ActivityChooserView.java and found next lines:

    LayoutInflater inflater = LayoutInflater.from(getContext());
    inflater.inflate(R.layout.abc_activity_chooser_view, this, true);

Then I followed to abc_activity_chooser_view.xml and saw:

<view xmlns:android="http://schemas.android.com/apk/res/android"
class="android.support.v7.internal.widget.ActivityChooserView$InnerLayout"
android:id="@+id/activity_chooser_view_content"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
style="?attr/activityChooserViewStyle">

<FrameLayout
    android:id="@+id/expand_activities_button"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:focusable="true"
    android:addStatesFromChildren="true"
    android:background="?attr/actionBarItemBackground">

    <ImageView android:id="@+id/image"
        android:layout_width="32dip"
        android:layout_height="32dip"
        android:layout_gravity="center"
        android:layout_marginTop="2dip"
        android:layout_marginBottom="2dip"
        android:layout_marginLeft="12dip"
        android:layout_marginRight="12dip"
        android:scaleType="fitCenter"
        android:adjustViewBounds="true" />

</FrameLayout>

<FrameLayout
    android:id="@+id/default_activity_button"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:focusable="true"
    android:addStatesFromChildren="true"
    android:background="?attr/actionBarItemBackground">

    <ImageView android:id="@+id/image"
        android:layout_width="32dip"
        android:layout_height="32dip"
        android:layout_gravity="center"
        android:layout_marginTop="2dip"
        android:layout_marginBottom="2dip"
        android:layout_marginLeft="12dip"
        android:layout_marginRight="12dip"
        android:scaleType="fitCenter"
        android:adjustViewBounds="true" />

</FrameLayout>

As you can see the sizes for image views are 32dp, when normally it should be 24dp.

EDIT:

The solution is simple - you create your own layout with the exact same name and put it into your resources folder. The only ammendment you gotta do to make things right is to change size of both image views like this:

                <ImageView android:id="@+id/image"
                   android:layout_width="24dip"
                   android:layout_height="24dip"
                   android:layout_gravity="center"
                   android:layout_margin="12dip"
                   android:scaleType="fitCenter"
                   android:adjustViewBounds="true"
                   tools:ignore="DuplicateIds"/>

P.S. Be advised that filenames and layouts may vary depending on app compat lib version, but the algorithm is the same.

Epidaurus answered 13/1, 2016 at 17:25 Comment(7)
Nice catch. I suggest you remove the full code segment and just point out the changes as that file has already changed in my build and required a manual edit. Getting frustrating how many of these hacks I've implemented to manage Android flaws. I have to track them so I can remember to remove them when they finally fix the issue two versions later. I've submitted a bug report for this issue.Kislev
This doesn't work for me. I make a new layout of the same name as the one being used (as described) and it seems as if it just ignores my layout and uses the existing one - is there something special I need to do to tell it to override layouts that have the same name?Belayneh
@MalcolmMacLeod Nothing special. 1) make sure u are giving the right name to activity chooser layout. Peek inside ActivityChooserView.java and find the line where it inflates its layout, it could have changed. 2) make sure u put the layout file to the right folder (you may have many of those in ur project with different resource modificators, e.g. "layout-large", etc.)Epidaurus
@MalcolmMacLeod *resource qualifiersEpidaurus
@DREDD112 hrm yes this is what I did, the layout that it inflates is (according to android studio) platforms/android-21/data/res/layout/activity_chooser_view.xml My app has only one layout folder res/layout I copy this into res/layout - and modify it a bit but it doesn't seem to change anything - one thing is that it complains about "style="?android:attr/activityChooserViewStyle" not being public - I remove this line from the layout, not sure if that plays a role.Belayneh
@MalcolmMacLeod >> platforms/android-21/data/res/layout/activity_chooser_view.xml well, this can mean two things: 1) you don't use the Toolbar from the support.v7 lib in ur project and the above workaround doesn't work with the framework implementation of Toolbar; 2) you have mixed up layouts and modified the framework version of the layout instead of the one from support.v7.Epidaurus
Thanks, that was indeed the problem - it seems this trick only works for AppCompat - after switching to AppCompat everything is good.Belayneh

© 2022 - 2024 — McMap. All rights reserved.