【问题标题】:Using png icon as drawable in NavigationDrawer在 NavigationDrawer 中使用 png 图标作为可绘制对象
【发布时间】:2016-05-22 01:56:50
【问题描述】:

提前致谢!

我在 NavigationDrawer 中更改图标时遇到问题,我在 NavigationDrawer 中使用 png 图像作为可绘制对象,但它会导致 InflaterException。我可以使用 png 或 Android 只接受 XML drawables 吗?

这是错误和代码!任何建议将不胜感激!

<?xml version="1.0" encoding="utf-8"?>

<group android:checkableBehavior="single">
    <item
        android:id="@+id/nav_cursos"
        android:icon="@drawable/ic_cursos"
        android:title="Cursos" />
    <item
        android:id="@+id/nav_gallery"
        android:icon="@drawable/ic_menu_gallery"
        android:title="Localización" />
    <item
        android:id="@+id/nav_slideshow"
        android:icon="@drawable/ic_menu_slideshow"
        android:title="Contacto" />
    <item
        android:id="@+id/nav_manage"
        android:icon="@drawable/ic_menu_manage"
        android:title="Tools" />
</group>

<item android:title="Communicate">
    <menu>
        <item
            android:id="@+id/nav_share"
            android:icon="@drawable/ic_menu_share"
            android:title="animaciones" />
        <item
            android:id="@+id/preferencias"
            android:icon="@drawable/ic_menu_send"
            android:title="preferencias" />
    </menu>
</item>

I have tried placing directly image on drawable, and changing drawables.xml too. Here:

<resources xmlns:android="http://schemas.android.com/apk/res/android">
<item name="ic_cursos" type="drawable">@drawable/ic_cursos</item>
<item name="ic_menu_gallery" type="drawable">@android:drawable/ic_menu_gallery</item>
<item name="ic_menu_slideshow" type="drawable">@android:drawable/ic_menu_slideshow</item>
<item name="ic_menu_manage" type="drawable">@android:drawable/ic_menu_manage</item>
<item name="ic_menu_share" type="drawable">@android:drawable/ic_menu_share</item>
<item name="ic_menu_send" type="drawable">@android:drawable/ic_menu_send</item>

但它总是失败。这里的错误:

Process: com.example.dani.provandodrawer, PID: 28495

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.dani.provandodrawer/com.example.dani.provandodrawer.MainActivity}: android.view.InflateException: Binary XML file line #16: Error inflating class android.support.design.widget.NavigationView

at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:811)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:627)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.view.InflateException: Binary XML file line #16: Error inflating class android.support.design.widget.NavigationView
at android.view.LayoutInflater.createView(LayoutInflater.java:620)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:696)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:256)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109)
at com.example.dani.provandodrawer.MainActivity.onCreate(MainActivity.java:40)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233) 
at android.app.ActivityThread.access$800(ActivityThread.java:135) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:136) 
at android.app.ActivityThread.main(ActivityThread.java:5001) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:515) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:811) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:627) 
at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.constructNative(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at android.view.LayoutInflater.createView(LayoutInflater.java:594)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:696) 
at android.view.LayoutInflater.rInflate(LayoutInflater.java:755) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:492) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:397) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:353) 
at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:256) 
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109) 
at com.example.dani.provandodrawer.MainActivity.onCreate(MainActivity.java:40) 
at android.app.Activity.performCreate(Activity.java:5231) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233) 
at android.app.ActivityThread.access$800(ActivityThread.java:135) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:136) 
at android.app.ActivityThread.main(ActivityThread.java:5001) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:515) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:811) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:627) 
at dalvik.system.NativeStart.main(Native Method) 
Caused by: android.content.res.Resources$NotFoundException: Resource is not a Drawable (color or path): TypedValue{t=0x1/d=0x7f02007f a=2 r=0x7f02007f}
at android.content.res.Resources.loadDrawable(Resources.java:2068)
at android.content.res.Resources.getDrawable(Resources.java:700)
at android.support.v4.content.ContextCompat.getDrawable(ContextCompat.java:323)
at android.support.v7.widget.TintManager.getDrawable(TintManager.java:147)
at android.support.v7.view.menu.MenuItemImpl.getIcon(MenuItemImpl.java:421)
at android.support.design.internal.NavigationMenuPresenter$NavigationMenuAdapter.prepareMenuItems(NavigationMenuPresenter.java:485)
at android.support.design.internal.NavigationMenuPresenter$NavigationMenuAdapter.update(NavigationMenuPresenter.java:426)
at android.support.design.internal.NavigationMenuPresenter.updateMenuView(NavigationMenuPresenter.java:113)
at android.support.design.widget.NavigationView.inflateMenu(NavigationView.java:233)
at android.support.design.widget.NavigationView.<init>(NavigationView.java:168)
at android.support.design.widget.NavigationView.<init>(NavigationView.java:94)
at java.lang.reflect.Constructor.constructNative(Native Method) 
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) 
at android.view.LayoutInflater.createView(LayoutInflater.java:594) 
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:696) 
at android.view.LayoutInflater.rInflate(LayoutInflater.java:755) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:492) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:397) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:353) 
at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:256) 
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109) 
at com.example.dani.provandodrawer.MainActivity.onCreate(MainActivity.java:40) 
at android.app.Activity.performCreate(Activity.java:5231) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233) 
at android.app.ActivityThread.access$800(ActivityThread.java:135) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:136) 
at android.app.ActivityThread.main(ActivityThread.java:5001) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:515) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:811) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:627) 
at dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

  • 我看到你正在使用 android drawables。只需尝试在您的项目中设置 android:icon="@android:drawable/ic_menu_..." 。如果要设置 png 图像,只需将 png 添加到 drawables 文件夹并将其设置为 android:icon="@drawable/my_image"
  • Hola Luis Miguel,感谢参赛者。 Lo tengo puesto como dices,solo que sin "android:" delante porque es un recurso mio,no del sistema。 Lo curioso es que no he encontrado nada en foros en internet, es raro!
  • Por usar image en .png 没有问题。 Prueba a quitar el fichero xml y usar directamente la imagen de la Caribbean drawables。 Es la única diferencia que veo con lo que suelo hacer。 Deberías usar siempre el inglés por aquí
  • 您好,再次删除 drawables.xml 会产生另一个错误。就像不支持 png 一样,但我在任何地方都找不到对这个问题的引用。
  • 哪个错误?我在一些项目中使用 png 作为图标,所以这不应该是原因。

标签: android icons png navigation-drawer


【解决方案1】:
Caused by: android.content.res.Resources$NotFoundException: Resource is not a Drawable (color or path): TypedValue{t=0x1/d=0x7f02007f a=2 r=0x7f02007f}
                                                   at android.content.res.Resources.loadDrawable(Resources.java:2068)

该错误表明可能图像资源未放置在可绘制文件夹中。将您的图像放在项目的 res/drawable 文件夹中。

【讨论】:

  • 嗨,Tafveez,图片在文件夹中...似乎与 png 的兼容性有关,但我认为这是可能的!
【解决方案2】:

在导航中使用 Drawable 的最佳方法是使用以下库... https://github.com/mikepenz/MaterialDrawer 相信我,它会为你节省很多时间。

编辑:这里有一些代码示例如何与drawable一起使用

public class AdvancedActivity extends AppCompatActivity {
private static final int PROFILE_SETTING = 1;

//save our header or result
private AccountHeader headerResult = null;
private Drawer result = null;

private IProfile profile;
private IProfile profile2;
private IProfile profile3;
private IProfile profile4;
private IProfile profile5;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sample);

    // Handle Toolbar
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setTitle(R.string.drawer_item_advanced_drawer);

    // Create a few sample profile
    profile = new ProfileDrawerItem().withName("Mike Penz").withEmail("mikepenz@gmail.com").withIcon(getResources().getDrawable(R.drawable.profile));
    profile2 = new ProfileDrawerItem().withName("Max Muster").withEmail("max.mustermann@gmail.com").withIcon(getResources().getDrawable(R.drawable.profile2)).withIdentifier(2);
    profile3 = new ProfileDrawerItem().withName("Felix House").withEmail("felix.house@gmail.com").withIcon(getResources().getDrawable(R.drawable.profile3));
    profile4 = new ProfileDrawerItem().withName("Mr. X").withEmail("mister.x.super@gmail.com").withIcon(getResources().getDrawable(R.drawable.profile4)).withIdentifier(4);
    profile5 = new ProfileDrawerItem().withName("Batman").withEmail("batman@gmail.com").withIcon(getResources().getDrawable(R.drawable.profile5));

    // Create the AccountHeader
    buildHeader(false, savedInstanceState);

    //Create the drawer
    result = new DrawerBuilder()
            .withActivity(this)
            .withToolbar(toolbar)
            .withAccountHeader(headerResult) //set the AccountHeader we created earlier for the header
            .addDrawerItems(
                    new PrimaryDrawerItem().withName(R.string.drawer_item_home).withIcon(FontAwesome.Icon.faw_home),
                    //here we use a customPrimaryDrawerItem we defined in our sample app
                    //this custom DrawerItem extends the PrimaryDrawerItem so it just overwrites some methods
                    new OverflowMenuDrawerItem().withName(R.string.drawer_item_menu_drawer_item).withDescription(R.string.drawer_item_menu_drawer_item_desc).withMenu(R.menu.fragment_menu).withOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                        @Override
                        public boolean onMenuItemClick(MenuItem item) {
                            Toast.makeText(AdvancedActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show();
                            return false;
                        }
                    }).withIcon(GoogleMaterial.Icon.gmd_filter_center_focus),
                    new CustomPrimaryDrawerItem().withBackgroundRes(R.color.accent).withName(R.string.drawer_item_free_play).withIcon(FontAwesome.Icon.faw_gamepad),
                    new PrimaryDrawerItem().withName(R.string.drawer_item_custom).withDescription("This is a description").withIcon(FontAwesome.Icon.faw_eye),
                    new CustomUrlPrimaryDrawerItem().withName(R.string.drawer_item_fragment_drawer).withDescription(R.string.drawer_item_fragment_drawer_desc).withIcon("https://avatars3.githubusercontent.com/u/1476232?v=3&s=460"),
                    new SectionDrawerItem().withName(R.string.drawer_item_section_header),
                    new SecondaryDrawerItem().withName(R.string.drawer_item_settings).withIcon(FontAwesome.Icon.faw_cart_plus),
                    new SecondaryDrawerItem().withName(R.string.drawer_item_help).withIcon(FontAwesome.Icon.faw_database).withEnabled(false),
                    new SecondaryDrawerItem().withName(R.string.drawer_item_open_source).withIcon(FontAwesome.Icon.faw_github),
                    new SecondaryDrawerItem().withName(R.string.drawer_item_contact).withSelectedIconColor(Color.RED).withIconTintingEnabled(true).withIcon(new IconicsDrawable(this, GoogleMaterial.Icon.gmd_plus).actionBar().paddingDp(5).colorRes(R.color.material_drawer_dark_primary_text)).withTag("Bullhorn"),
                    new SecondaryDrawerItem().withName(R.string.drawer_item_help).withIcon(FontAwesome.Icon.faw_question).withEnabled(false)
            ) // add the items we want to use with our Drawer
            .withOnDrawerNavigationListener(new Drawer.OnDrawerNavigationListener() {
                @Override
                public boolean onNavigationClickListener(View clickedView) {
                    //this method is only called if the Arrow icon is shown. The hamburger is automatically managed by the MaterialDrawer
                    //if the back arrow is shown. close the activity
                    AdvancedActivity.this.finish();
                    //return true if we have consumed the event
                    return true;
                }
            })
            .addStickyDrawerItems(
                    new SecondaryDrawerItem().withName(R.string.drawer_item_settings).withIcon(FontAwesome.Icon.faw_cog).withIdentifier(10),
                    new SecondaryDrawerItem().withName(R.string.drawer_item_open_source).withIcon(FontAwesome.Icon.faw_github)
            )
            .withSavedInstance(savedInstanceState)
            .build();


}

/**
 * small helper method to reuse the logic to build the AccountHeader
 * this will be used to replace the header of the drawer with a compact/normal header
 *
 * @param compact
 * @param savedInstanceState
 */
private void buildHeader(boolean compact, Bundle savedInstanceState) {
    // Create the AccountHeader
    headerResult = new AccountHeaderBuilder()
            .withActivity(this)
            .withHeaderBackground(R.drawable.header)
            .withCompactStyle(compact)
            .addProfiles(
                    profile,
                    profile2,
                    profile3,
                    profile4,
                    profile5,
                    //don't ask but google uses 14dp for the add account icon in gmail but 20dp for the normal icons (like manage account)
                    new ProfileSettingDrawerItem().withName("Add Account").withDescription("Add new GitHub Account").withIcon(new IconicsDrawable(this, GoogleMaterial.Icon.gmd_plus).actionBar().paddingDp(5).colorRes(R.color.material_drawer_dark_primary_text)).withIdentifier(PROFILE_SETTING),
                    new ProfileSettingDrawerItem().withName("Manage Account").withIcon(GoogleMaterial.Icon.gmd_settings)
            )
            .withOnAccountHeaderListener(new AccountHeader.OnAccountHeaderListener() {
                @Override
                public boolean onProfileChanged(View view, IProfile profile, boolean current) {
                    //sample usage of the onProfileChanged listener
                    //if the clicked item has the identifier 1 add a new profile ;)
                    if (profile instanceof IDrawerItem && ((IDrawerItem) profile).getIdentifier() == PROFILE_SETTING) {
                        IProfile newProfile = new ProfileDrawerItem().withNameShown(true).withName("Batman").withEmail("batman@gmail.com").withIcon(getResources().getDrawable(R.drawable.profile5));
                        if (headerResult.getProfiles() != null) {
                            //we know that there are 2 setting elements. set the new profile above them ;)
                            headerResult.addProfile(newProfile, headerResult.getProfiles().size() - 2);
                        } else {
                            headerResult.addProfiles(newProfile);
                        }
                    }

                    //false if you have not consumed the event and it should close the drawer
                    return false;
                }
            })
            .withSavedInstance(savedInstanceState)
            .build();
}

【讨论】:

    【解决方案3】:

    Android 只接受导航抽屉菜单的矢量图标。因此,为了让您将 png 图标加载为矢量,首先使用 https://image.online-convert.com/convert-to-svg 等工具将其转换为 SVG 文件。之后在 Android Studio 中右键单击您的可绘制文件夹并选择 New,然后导航到 Vector Asset。在 Asset Type 上选择 Local File(SVG, PSD) 并输入 SVG 文件的路径并找出其余部分。我希望这对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 2016-01-26
      • 1970-01-01
      • 2022-10-31
      • 2013-12-11
      • 2011-12-13
      • 2014-07-19
      • 2015-08-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多