Clans / FloatingActionButton

Android Floating Action Button based on Material Design specification
Apache License 2.0
5.23k stars 1.13k forks source link

Vector drawable not supported #273

Open yomiolatunji opened 8 years ago

yomiolatunji commented 8 years ago

I try to use vector drawable but the image does not show

<com.github.clans.fab.FloatingActionButton
            android:id="@+id/fab22"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:srcCompat="@drawable/ic_message"
            app:fab_label="New Message"
            style="@style/MenuButtonsStyle" />
Ostkontentitan commented 8 years ago

I work with vector drawables but use android:src="@drawable/ic_fab_new" instead. Works well.

yomiolatunji commented 8 years ago

But android:src="@drawable/ic_fab_new" won't work on pre-lollipop devices

Ostkontentitan commented 8 years ago

your right, my bad!

Edit I tested this with API 16 and all the icons show properly.

My vector drawables are in xml fromat:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#FFFFFFFF"
        android:pathData="M12,2C8.14,2 5,5.1...."/>
</vector>
gwilli commented 8 years ago

Would really like if it would support app:srcCompat="@drawable/my_vector_icon" like in Chris Bane's blog post: https://medium.com/@chrisbanes/appcompat-v23-2-age-of-the-vectors-91cbafa87c88#.w8pm9pc4w

This gives the ability to remove all generated pngs for a smaller apk.

Is this something you're working on?

gwilli commented 8 years ago

I would still like to see this enhancement, but until it happens @dovercomer you can do what I do and wrap the vector drawables you want to use for your FloatingActionButton in an InsetDrawable.

Here's my file res/drawable/fab_add_white.xml:

<?xml version="1.0" encoding="utf-8"?>
<!-- Wrapping the vector drawable in an inset drawable to take advantage of the "magic" way
documented in Chris Bane's blog post:
https://medium.com/@chrisbanes/appcompat-v23-2-age-of-the-vectors-91cbafa87c88#.w8pm9pc4w

This is needed because clans' FAB and FAM don't support AppCompat's app:srcCompat parameter *yet* 
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_add_white" />

and then in my layout:

<com.github.clans.fab.FloatingActionButton
            android:id="@+id/add_fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/fab_add_white"
            style="@style/FloatingAction.Button" />

If you're using appCompat version 23.2.0, it should just work. If you're using 23.4.0 or later, you'll need to add this line to your Activity. (I put it in my BaseActivity):

    static {
        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
    }

Hope that helps!

koroshiya commented 8 years ago

You can get a decent implementation going by making a few small additions to the attrs.xml and FloatingActionButton.java files. However, this includes adding a dependency on support-vector-drawable, so I don't know if that's something the project maintainers would be cool with (I can add a PR if it is desirable).

For anyone wanting app:srcCompat, the modifications are:

1: add

compile 'com.android.support:support-vector-drawable:23.4.0' to the dependencies block in this library's build.gradle file.

2: add

<attr name="srcCompat" format="reference"/> to the <declare-styleable name="FloatingActionButton"> style in this library's attrs.xml file.

3: modify the init(Contect, AttributeSet, int) method of FloatingActionButton and add:

if (attr.hasValue(R.styleable.FloatingActionButton_srcCompat)){
    final int id = attr.getResourceId(R.styleable.FloatingActionButton_srcCompat, -1);
    if (id != -1) {
        Drawable d;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            d = context.getDrawable(id);
        }else{
            d = VectorDrawableCompat.create(context.getResources(), id, null);
        }
        setImageDrawable(d);
    }
}

after the other attr.hasValue if statement blocks.

I believe that's all I needed to change. I've tested this with vector graphics on Android 4.1 through the emulator, as well as Android 6 on a physical device, and both displayed the vector on the FAB as expected.

codeversed commented 7 years ago

You can simply do it like this, or if you wanted you could use two different layouts. Either way, works fine.

android:src="@drawable/vector_file" app:srcCompat="@drawable/vector_file" tools:ignore="VectorDrawableCompat"

I would avoid AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); due to some serious performance issues.

Fuhrmann commented 7 years ago

@codeversed your solution did not worked for me using API 19.

Instead of specifying android:src or event app:srcCompat, I set the drawable image in my activity/fragment:

FloatingActionButton myFab = (FloatingActionButton) getActivity()
        .findViewById(R.id.fab_add_animal);

myFab.setImageDrawable(
        AppCompatDrawableManager.get().getDrawable(getActivity(), R.drawable.ic_add_white_24dp)
);

I'm not using setCompatVectorFromResourcesEnabled(true), only vectorDrawables.useSupportLibrary = true in my app gradle file and and I found the solution to this problem here.

varadmondkar commented 6 years ago
myFab.setImageDrawable(
        AppCompatDrawableManager.get().getDrawable(getActivity(), R.drawable.ic_add_white_24dp)
);

Throws warning for me.

AppCompatDrawableManager can only be called from within the same library group (groupId=com.android.support)

I used ContextCompat instead

myFab.setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.ic_add_white_24dp));