JoanZapata / android-iconify

Android integration of multiple icon providers such as FontAwesome, Entypo, Typicons,...
http://joanzapata.com/android-iconify
Other
3.93k stars 526 forks source link

Cannot Use it in NavigationView #93

Closed syedalinaqi closed 9 years ago

syedalinaqi commented 9 years ago

I cannot use it in NavigationView. I tried the Following Code:

        Drawable icon = new IconDrawable(this, Iconify.IconValue.fa_envelope).colorRes(R.color.colorAccent).actionBarSize();
        navigationView.getMenu().findItem(R.id.nav_first_fragment).setIcon(icon);

The Following is the Log:

07-27 03:16:42.887  32197-32197/com.i10studios.websiteinformer E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.NullPointerException
            at android.support.design.internal.NavigationMenuItemView.setIcon(NavigationMenuItemView.java:113)
            at android.support.design.internal.NavigationMenuItemView.initialize(NavigationMenuItemView.java:72)
            at android.support.design.internal.NavigationMenuPresenter$NavigationMenuAdapter.getView(NavigationMenuPresenter.java:305)
            at android.widget.HeaderViewListAdapter.getView(HeaderViewListAdapter.java:230)
            at android.widget.AbsListView.obtainView(AbsListView.java:2603)
            at android.widget.ListView.makeAndAddView(ListView.java:1840)
            at android.widget.ListView.fillDown(ListView.java:681)
            at android.widget.ListView.fillFromTop(ListView.java:742)
            at android.widget.ListView.layoutChildren(ListView.java:1661)
            at android.widget.AbsListView.onLayout(AbsListView.java:2426)
            at android.view.View.layout(View.java:14905)
            at android.view.ViewGroup.layout(ViewGroup.java:4601)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
            at android.view.View.layout(View.java:14905)
            at android.view.ViewGroup.layout(ViewGroup.java:4601)
            at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:931)
            at android.view.View.layout(View.java:14905)
            at android.view.ViewGroup.layout(ViewGroup.java:4601)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
            at android.view.View.layout(View.java:14905)
            at android.view.ViewGroup.layout(ViewGroup.java:4601)
            at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1694)
            at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1552)
            at android.widget.LinearLayout.onLayout(LinearLayout.java:1465)
            at android.view.View.layout(View.java:14905)
            at android.view.ViewGroup.layout(ViewGroup.java:4601)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
            at android.view.View.layout(View.java:14905)
            at android.view.ViewGroup.layout(ViewGroup.java:4601)
            at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1694)
            at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1552)
            at android.widget.LinearLayout.onLayout(LinearLayout.java:1465)
            at android.view.View.layout(View.java:14905)
            at android.view.ViewGroup.layout(ViewGroup.java:4601)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
            at android.view.View.layout(View.java:14905)
            at android.view.ViewGroup.layout(ViewGroup.java:4601)
            at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2213)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2027)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1237)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5162)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:791)
            at android.view.Choreographer.doCallbacks(Choreographer.java:591)
            at android.view.Choreographer.doFrame(Choreographer.java:561)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:777)
            at android.os.Handler.handleCallback(Handler.java:725)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:176)
            at android.app.ActivityThread.main(ActivityThread.java:5317)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
            at dalvik.system.NativeStart.main(Native Method)
PsyGik commented 9 years ago

What version of android.support.design are you using?

marcosmbbrito commented 9 years ago

Same problem with me. I'm using The latest one. It was working, but don't know what happen today is not working. Maybe is because I deleted play-services in graddle. I will continue to test later

NoelChew commented 9 years ago

I am facing the same issue. Here is my code:

navigationView.getMenu().findItem(R.id.nav_home).setIcon(new IconDrawable(this, Iconify.IconValue.fa_home).colorRes(R.color.default_primary_color));

I am using:

compile 'com.android.support:design:22.2.1'
compile 'com.joanzapata.android:android-iconify:1.0.10'

Here is the error code:

PID: 30536
    java.lang.NullPointerException: Attempt to invoke virtual method 'android.graphics.drawable.Drawable android.graphics.drawable.Drawable$ConstantState.newDrawable()' on a null object reference
            at android.support.design.internal.NavigationMenuItemView.setIcon(NavigationMenuItemView.java:113)
            at android.support.design.internal.NavigationMenuItemView.initialize(NavigationMenuItemView.java:72)
            at android.support.design.internal.NavigationMenuPresenter$NavigationMenuAdapter.getView(NavigationMenuPresenter.java:305)
            at android.widget.HeaderViewListAdapter.getView(HeaderViewListAdapter.java:220)
            at android.widget.AbsListView.obtainView(AbsListView.java:2347)
            at android.widget.ListView.makeAndAddView(ListView.java:1864)
            at android.widget.ListView.fillDown(ListView.java:698)
            at android.widget.ListView.fillFromTop(ListView.java:759)
            at android.widget.ListView.layoutChildren(ListView.java:1659)
            at android.widget.AbsListView.onLayout(AbsListView.java:2151)
            at android.view.View.layout(View.java:15671)
            at android.view.ViewGroup.layout(ViewGroup.java:5038)
            at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
            at android.view.View.layout(View.java:15671)
            at android.view.ViewGroup.layout(ViewGroup.java:5038)
            at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:931)
            at android.view.View.layout(View.java:15671)
            at android.view.ViewGroup.layout(ViewGroup.java:5038)
            at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
            at android.view.View.layout(View.java:15671)
            at android.view.ViewGroup.layout(ViewGroup.java:5038)
            at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
            at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
            at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
            at android.view.View.layout(View.java:15671)
            at android.view.ViewGroup.layout(ViewGroup.java:5038)
            at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
            at android.view.View.layout(View.java:15671)
            at android.view.ViewGroup.layout(ViewGroup.java:5038)
            at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
            at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
            at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
            at android.view.View.layout(View.java:15671)
            at android.view.ViewGroup.layout(ViewGroup.java:5038)
            at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
            at android.view.View.layout(View.java:15671)
            at android.view.ViewGroup.layout(ViewGroup.java:5038)
            at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2086)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1843)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1061)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5885)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
            at android.view.Choreographer.doCallbacks(Choreographer.java:580)
            at android.view.Choreographer.doFrame(Choreographer.java:550)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5254)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
JoanZapata commented 9 years ago

I don't think its related to Iconify. Have you tried that?

NoelChew commented 9 years ago

The suggested solution asked to use local drawables.

JoanZapata commented 9 years ago

Local drawables or build tools version 22.2.0. What is your build tools version? Can you try with version "22.2.0"?

NoelChew commented 9 years ago

There is no error when I am using com.android.support:design:22.2.0 The error only occurs when I am using com.android.support:design:22.2.1

JoanZapata commented 9 years ago

As I said, it's not related to Iconify. Wait for version 22.2.2 and see if the bug is still present. In the meanwhile I'm closing this issue if that's ok.

marcosmbbrito commented 9 years ago

Just for info, this are the methods lines diff that is causing the NullPointerException:

public void setIcon(Drawable icon) { if(icon != null) { icon = DrawableCompat.wrap(icon.getConstantState().newDrawable()).mutate(); ...

fuwaneko commented 9 years ago

Unfortunately, this is still present in v23 of support design library which came out recently.

And this is not support design library bug, it's iconify bug.

You must override getConstantState() and implement Drawable.ConstantState for any Drawable subclasses because by default it returns null. I subclassed IconDrawable, added outline feature for icons and implemented aforementioned class and method. Now NavigationView works. Also it's quite hard to extend your class, because properties and static methods are private instead of protected.

See this gist for details.

1zaman commented 8 years ago

This was actually a bug in the design support library implementation. Constant states were created only to support preloading framework drawables from resources, and are not supposed to be implemented by third-party implementations. However, for some reason mutating the drawable didn't seem to properly disassociate the icon drawable in NavigationView from using the global state, and a new instance needed to be created via the constant state and then mutated in order to resolve this. This resulted in this bug, as it didn't check that the drawable actually supported constant state before using it.

It looks like this has been fixed in version 23.1.0, which does add a null check for it. I have nonetheless added constant state support in #134, as there are similar bugs in the framework itself (e.g. LayerDrawable also uses constant state to generate new instances of it's children upon mutation).

fuwaneko commented 8 years ago

@1zaman I think Android itself sort of expects constant state to be implemented on Drawable subclasses, but it's not stated in the documentation. Way too much bugs related to it.

1zaman commented 8 years ago

I think it’s just sloppy (and usually wrong) coding by the framework developers, that persisted because all the framework's own drawable implementations uses constant states, and third-party drawables implementations are quite few and far between, and usually don’t interact with the framework implementations (especially since they can’t be defined in XML). LayerDrawable also had a few other bugs that were fixed at various occasions (and some that still persist, e.g. I just encountered and reported http://b.android.com/191795).

On 28-Oct-2015, at 2:45 PM, Dmitry Gorbunov notifications@github.com wrote:

@1zaman https://github.com/1zaman I think Android itself sort of expects constant state to be implemented on Drawable subclasses, but it's not stated in the documentation. Way too much bugs related to it.

— Reply to this email directly or view it on GitHub https://github.com/JoanZapata/android-iconify/issues/93#issuecomment-151782402.

fuwaneko commented 8 years ago

@1zaman yes, that's what I meant. Thanks for fixes, by the way.