Android的drawable目录可以包含子目录吗?

发布于 2024-07-26 21:42:04 字数 379 浏览 8 评论 0原文

在 Android SDK 文档中,使用 @drawable/my_image xml 语法的所有示例都直接寻址存储在我的项目的 res/drawable 目录中的图像。

我想知道在可绘制目录中创建子目录是否明确是不行的。

例如,如果我有以下目录布局:

res/drawable
-- sandwiches
  -- tunaOnRye.png
  -- hamAndSwiss.png
-- drinks
  -- coldOne.png
  -- hotTea.png

我可以将金枪鱼沙拉三明治的图像引用为 @drawable/sandwiches/tunaOnRye

或者我是否必须在可绘制目录中保持层次结构平坦。

In the Android SDK documentation, all of the examples used with the @drawable/my_image xml syntax directly address images that are stored in the res/drawable directory in my project.

I am wondering if it is explicitly not okay to create a sub directory within the drawable directory.

For example, if I had the following directory layout:

res/drawable
-- sandwiches
  -- tunaOnRye.png
  -- hamAndSwiss.png
-- drinks
  -- coldOne.png
  -- hotTea.png

Could I reference the image of a tuna salad sandwich as @drawable/sandwiches/tunaOnRye

Or do I have to keep the hierarchy flat in the drawable directory.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(23

古镇旧梦 2024-08-02 21:42:04

不,资源机制不支持可绘制目录中的子文件夹,所以是的 - 您需要保持该层次结构平坦。

您显示的目录布局将导致没有任何图像可用。

根据我自己的实验,在 res/drawable 文件夹中创建一个包含任何项目的子文件夹似乎会导致资源编译器失败 - 阻止 R.java 文件无法正确生成。

No, the resources mechanism doesn't support subfolders in the drawable directory, so yes - you need to keep that hierarchy flat.

The directory layout you showed would result in none of the images being available.

From my own experiments it seems that having a subfolder with any items in it, within the res/drawable folder, will cause the resource compiler to fail -- preventing the R.java file from being generated correctly.

榕城若虚 2024-08-02 21:42:04

我正在使用的解决方法(Android 本身似乎喜欢的方法)是本质上用下划线代替正斜杠,因此您的结构将如下所示:

sandwich_tunaOnRye.png
sandwich_hamAndSwiss.png
drink_coldOne.png
drink_hotTea.png

该方法要求您在命名时一丝不苟,并且不使处理文件本身变得更加容易(如果您决定饮料和三明治实际上都应该是“food”,您必须进行批量重命名,而不是简单地将它们移动到目录中) ; 但与等效的文件夹结构相比,您的编程逻辑的复杂性并没有受到太严重的影响。

这种情况确实很糟糕。 Android 是一个混合体,既有精彩的设计决策,也有糟糕的设计决策。 我们只能希望后一部分能够尽快被淘汰:)

The workaround I'm using (and the one Android itself seems to favor) is to essentially substitute an underscore for a forward slash, so your structure would look something like this:

sandwich_tunaOnRye.png
sandwich_hamAndSwiss.png
drink_coldOne.png
drink_hotTea.png

The approach requires you to be meticulous in your naming and doesn't make it much easier to wrangle the files themselves (if you decided that drinks and sandwiches should really all be "food", you'd have to do a mass rename rather than simply moving them to the directory); but your programming logic's complexity doesn't suffer too badly compared to the folder structure equivalent.

This situation sucks indeed. Android is a mixed bag of wonderful and terrible design decisions. We can only hope for the latter portion to get weeded out with all due haste :)

作死小能手 2024-08-02 21:42:04

实际上,在 Android Studio 上这是可能的。 您可以拥有嵌套资源,如下所示此处

在此处输入图像描述

此处还有一个用于对资源进行分组的插件。

不过我建议避免这种情况。

Actually, on Android Studio it is possible. You can have nested resources as shown here :

enter image description here

There is also a plugin to group resources here.

I recommend to avoid this though.

格子衫的從容 2024-08-02 21:42:04

是的 - 它确实很糟糕:)但是您可以使用资产文件夹并在其中包含子目录并以这种方式加载图像。

Yes - it does suck :) However you can use the assets folder and have sub directories in there and load images that way.

雨落□心尘 2024-08-02 21:42:04

使用资产文件夹。

示例代码:

InputStream is = null;
try {
    is = this.getResources().getAssets().open("test/sample.png");
} catch (IOException e) {
    ;
}

image = BitmapFactory.decodeStream(is);

Use assets folder.

sample code:

InputStream is = null;
try {
    is = this.getResources().getAssets().open("test/sample.png");
} catch (IOException e) {
    ;
}

image = BitmapFactory.decodeStream(is);
魂归处 2024-08-02 21:42:04

我编写了一个 eclipse 插件,它允许通过用两个下划线 __ 分隔文件名来创建虚拟子文件夹。 该项目还处于早期阶段,但不用担心它不会使您的 IDE 崩溃,

可以在此处找到更多详细信息,请随意分叉并发送拉取请求:

https://github.com/kirill578/Android-Sorted-Res-Folder

在此处输入图像描述

I've wrote an eclipse plugin which allows to create virtual subfolder by separating the file name with two underscores __. The project is in early stages, but don't worry it won't crash your IDE

more details can be found here, feel free to fork and send pull requests:

https://github.com/kirill578/Android-Sorted-Res-Folder

enter image description here

不喜欢何必死缠烂打 2024-08-02 21:42:04

我喜欢使用简单的脚本将设计人员提供的有组织的目录结构展平为可用于生成 R 文件的内容。

使用drawable-hdpi中的当前路径运行:

#! /bin/bash
DIRS=`find * -type d`
for dir in ${DIRS} ; do 
  for file in `ls ${dir}` ; do
    mv ${dir}/${file}  ${dir}_${file};
  done 
  rmdir ${dir};
done

I like to use a simple script to flatten an organized directory structure provided by designers to something that can be used to generate an R file.

Run with current path in drawable-hdpi:

#! /bin/bash
DIRS=`find * -type d`
for dir in ${DIRS} ; do 
  for file in `ls ${dir}` ; do
    mv ${dir}/${file}  ${dir}_${file};
  done 
  rmdir ${dir};
done
与风相奔跑 2024-08-02 21:42:04

在带有 gradle 的 android studio 中,您可以拥有多个源控制器,这将允许您分离资源。 例如:

android {
    ....
    android.sourceSets {
        main.res.srcDirs = ['src/main/extraresdirnamed_sandwiches', 'src/main/res']
    }
    ....
}

但是,名称不能冲突,这意味着您仍然需要使用诸如三明治_tunaOnRye 之类的名称,但您将能够为所有三明治提供单独的部分。

这允许您将资源存储在不同的结构中(对于自动生成的内容很有用,例如actionbargenerator)

In android studio with gradle you can have multiple source directors which will allow you to separate resources. For example:

android {
    ....
    android.sourceSets {
        main.res.srcDirs = ['src/main/extraresdirnamed_sandwiches', 'src/main/res']
    }
    ....
}

However the names must not collide which means you will still need to have names such as sandwiches_tunaOnRye but you will be able to have a seperate section for all of your sandwiches.

This allows you to store your resources in different structures (useful for auto generated content such as actionbargenerator)

迷雾森÷林ヴ 2024-08-02 21:42:04

部分解决该问题的一种方法是使用 API 级别后缀。
我使用 res/layout-v1、res/layout-v2 等在同一个 apk 中保存多个子项目。
该机制可用于所有资源类型。

显然,只有当您的目标 API 级别高于 res/layout-v 时,才可以使用此方法? 您正在使用。

另外,请注意 Android 1.5 和 1.6 中的错误。
请参阅有关 API 级别后缀的 Android 文档

One way to partially get around the problem is to use the API Level suffix.
I use res/layout-v1, res/layout-v2 etc to hold multiple sub projects in the same apk.
This mechanism can be used for all resource types.

Obviously, this can only be used if you are targeting API levels above the res/layout-v? you are using.

Also, watch out for the bug in Android 1.5 and 1.6.
See Andoroid documentation about the API Level suffix.

四叶草在未来唯美盛开 2024-08-02 21:42:04

对于这种情况有一个解决方法:您可以在与默认 res 文件夹同一级别创建一个 resVector(例如)文件夹。 您可以在那里添加任何 drawable-xxx 资源文件夹:

resVector
-drawable
-layout
-color

之后您只需添加

sourceSets {
        main.res.srcDirs += 'src/main/resVector'
    }

build.gradle 文件中(在 android { })。

There is a workaround for this situation: you can create a resVector (for example) folder on the same level as default res folder. There you can add any drawable-xxx resource folders there:

resVector
-drawable
-layout
-color

After that all you need is to add

sourceSets {
        main.res.srcDirs += 'src/main/resVector'
    }

into your build.gradle file (inside android { }).

鹊巢 2024-08-02 21:42:04

随着图书馆系统的出现,为每个大资产集创建一个图书馆可能是一个解决方案。

这仍然是个问题,因为必须避免在所有资产中使用相同的名称,但每个库使用前缀方案应该会有所帮助。

它并不像创建文件夹那么简单,但这有助于保持一切正常......

With the advent of library system, creating a library per big set of assets could be a solution.

It is still problematic as one must avoid using the same names within all the assets but using a prefix scheme per library should help with that.

It's not as simple as being able to create folders but that helps keeping things sane...

格子衫的從容 2024-08-02 21:42:04

这不是完美的方法。 您必须以相同的方式实现显示

也可以通过你可以使用的代码调用文件夹下的图片

Resources res = getResources();
Drawable shape = res. getDrawable(R.drawable.gradient_box);

TextView tv = (TextView)findViewByID(R.id.textview);
tv.setBackground(shape);

This is not perfect methods. You have to implement same way which is display here.

You can also call the image under the folder through the code you can use

Resources res = getResources();
Drawable shape = res. getDrawable(R.drawable.gradient_box);

TextView tv = (TextView)findViewByID(R.id.textview);
tv.setBackground(shape);
提笔落墨 2024-08-02 21:42:04

不是我的,但我在寻找这个问题时发现了这个线程,如果您使用 Android Studio 和 Gradle Build 系统,它非常简单,不需要插件,只需一点构建文件编辑

https://stackoverflow.com/a/22426467/618419

Not mine but I found this thread when looking for this issue, if your using Android Studio and Gradle Build system its pretty easy no plugins necessary just a little build file editing

https://stackoverflow.com/a/22426467/618419

自我难过 2024-08-02 21:42:04

Gradle 与 Android Studio 可以这样做(链接)。

它在“配置结构”段落中

sourceSets {
 main {
    java {
        srcDir 'src/java'
    }
    resources {
        srcDir 'src/resources'
    }
 }
}

Gradle with Android Studio could do it this way (link).

It's in the paragraph "Configuring the Structure"

sourceSets {
 main {
    java {
        srcDir 'src/java'
    }
    resources {
        srcDir 'src/resources'
    }
 }
}
凉世弥音 2024-08-02 21:42:04

在 main 中创建一个文件夹。
像:'res_notification_btn'

并创建树文件夹。像'drawable'或'layout'

然后在'build.gradle'中添加这个

sourceSets
            {
                main
                {
                    res
                    {
                        srcDirs = ['src/main/res_notification_btn', 'src/main/res']
                      or
                        srcDir 'src/main/res_notification_btn'
                    }
                }
            }

create a folder in main.
like: 'res_notification_btn'

and create tree folder in. like 'drawable' or 'layout'

then in 'build.gradle' add this

sourceSets
            {
                main
                {
                    res
                    {
                        srcDirs = ['src/main/res_notification_btn', 'src/main/res']
                      or
                        srcDir 'src/main/res_notification_btn'
                    }
                }
            }
oО清风挽发oО 2024-08-02 21:42:04
#!/usr/bin/env ruby

# current dir should be drawable-hdpi/ etc

# nuke all symlinks
Dir.foreach('.') {|f|
    File.delete(f) if File.symlink?(f)
}

# symlink all resources renaming with underscores
Dir.glob("**/*.png") {|f|
    system "ln -s #{f} #{f.gsub('/', '_')}" if f.include?("/")
}
#!/usr/bin/env ruby

# current dir should be drawable-hdpi/ etc

# nuke all symlinks
Dir.foreach('.') {|f|
    File.delete(f) if File.symlink?(f)
}

# symlink all resources renaming with underscores
Dir.glob("**/*.png") {|f|
    system "ln -s #{f} #{f.gsub('/', '_')}" if f.include?("/")
}
花开半夏魅人心 2024-08-02 21:42:04

检查将文件夹层次结构转换为单个文件夹的 Bash 展平文件夹脚本

Check Bash Flatten Folder script that converts folder hierarchy to a single folder

完美的未来在梦里 2024-08-02 21:42:04

资产/
您可以使用它来存储原始资源文件。 您在此处保存的文件将按原样编译为 .apk 文件,并保留原始文件名。 您可以使用 URI 以与典型文件系统相同的方式导航此目录,并使用 AssetManager 将文件作为字节流读取。 例如,这是纹理和游戏数据的好位置。
http://developer.android.com/tools/projects/index.html

assets/
You can use it to store raw asset files. Files that you save here are compiled into an .apk file as-is, and the original filename is preserved. You can navigate this directory in the same way as a typical file system using URIs and read files as a stream of bytes using the AssetManager. For example, this is a good location for textures and game data.
http://developer.android.com/tools/projects/index.html

執念 2024-08-02 21:42:04

不允许使用子目录,资源必须仅包含 [a-z0-9_.]。

不,你有大写字母,并且没有正斜杠。

Subdirectories are not allowed, the resource must contain only [a-z0-9_.].

No you have uppercase letters, and no forward slashes.

小巷里的女流氓 2024-08-02 21:42:04

可以通过一个与“res”平行的额外文件夹和一个子目录“drawable”来拥有多个可绘制文件夹,然后将以下内容添加到 gradle:

sourceSets {
    main {
        res.srcDirs 'src/main/<extra_res>'
    }
}

使用 gradle 6.5.1 进行测试

It is possible to have multiple drawable folders by having an extra folder parallel to 'res' with a subdirectory 'drawable' and then add following to gradle:

sourceSets {
    main {
        res.srcDirs 'src/main/<extra_res>'
    }
}

Tested with gradle 6.5.1

污味仙女 2024-08-02 21:42:04

对于任何使用 Xamarin(Xamarin.Android 或 Xamarin.Forms)的人来说,有一种方法可以做到这一点。

在 Android 项目的 .csproj 文件中,找到 MonoAndroidResourcePrefix 行(记录得很差,此处)。 在此处添加您要使用的子目录,并用分号分隔每个条目。 构建时,Visual Studio 会删除这些前缀,以便所有资源最终都处于平面层次结构中。 进行这些更改后,您可能需要重新加载解决方案。

示例在 Xamarin 中设置

这些目录不需要是项目中默认资源目录的子目录。

确保您添加的文件将构建操作设置为“AndroidResource”。

对于 Xamarin.Android,可视化编辑器无法识别图像,并将显示错误“无法解析此资源 URL”,但项目将构建并且图像将在运行时可见。

错误编辑器
示例模拟器

For anyone using Xamarin (either Xamarin.Android or Xamarin.Forms), there is a way to do this.

In the .csproj file for the Android project find the line for MonoAndroidResourcePrefix (documented, though rather poorly, here). Add the subdirectories you are wanting to use here, separating each entry by semicolons. When building, Visual Studio strips these prefixes so that all of the resources end up in a flat hierarchy. You may need to reload the solution after making these changes.

Example of setup in Xamarin

These directories do not need to be subdirectories of the default Resources directory in the project.

Make sure that files you add are getting the build action set to "AndroidResource".

For Xamarin.Android, the visual editor won't recognize images and will show the error "This resource URL cannot be resolved" but the project will build and the image will be visible at runtime.

Error in editor
Example in emulator

鲜肉鲜肉永远不皱 2024-08-02 21:42:04

我想将我所有的绘图组织成类别。 使用常规目录结构无法实现这一点,因此我的解决方案是构建以下目录结构:

- res
    - drawable
- organised_res
    - category1
          - drawable
    - category2
          - drawable
    - ...
    - categoryn
          - drawable

然后让 gradle 了解我添加的所有新资源目录:
在 build.gradle.kts 中,在 android 元素下我添加了:

sourceSets.getByName("main") {
    res.srcDirs("src/main/organised_res/category1",
                "src/main/organised_res/category2",
                ...
                "src/main/organised_res/categoryn")
}

重要的是要考虑到所有类别(和其他资源)的所有可绘制文件夹将合并为一个非分层平面结构,因此一个 pic.jpg 位于一个这些目录可以通过代码简单地访问,如 R.drawable.pic。 因此,确保所有文件名都是唯一的非常重要。

I wanted to organize all my drawables into categories. This cannot be achieved using the regular directory structure, so my solution was to build the following directory structure:

- res
    - drawable
- organised_res
    - category1
          - drawable
    - category2
          - drawable
    - ...
    - categoryn
          - drawable

And then let gradle know about all the new resource directories I added:
In build.gradle.kts, under android element I added:

sourceSets.getByName("main") {
    res.srcDirs("src/main/organised_res/category1",
                "src/main/organised_res/category2",
                ...
                "src/main/organised_res/categoryn")
}

It's important to take into account that all drawable folders of all categories (and other resources) will be merged into a single non-hierarchical flat structure, so a pic.jpg in one of those dirs can be accessed from code simply as R.drawable.pic. Therefore it's important to make sure that all file names are unique.

缱倦旧时光 2024-08-02 21:42:04
  1. 右键单击 Drawable
  2. 选择 New ---> 目录
  3. 输入目录名称。 例如:logo.png(默认位置已显示drawable文件夹)
  4. 将图像直接复制并粘贴到drawable文件夹中。 粘贴时,您可以选择为列表中的每个图像选择 mdpi/xhdpi/xxhdpi 等。 选择适当的选项并输入图像的名称。 确保与目录名称保持相同的名称,即 logo.png
  5. 对其余图像执行相同的操作。 所有这些都将放置在 logo.png 主文件夹下。
  1. Right click on Drawable
  2. Select New ---> Directory
  3. Enter the directory name. Eg: logo.png(the location will already show the drawable folder by default)
  4. Copy and paste the images directly into the drawable folder. While pasting you get an option to choose mdpi/xhdpi/xxhdpi etc for each of the images from a list. Select the appropriate option and enter the name of the image. Make sure to keep the same name as the directory name i.e logo.png
  5. Do the same for the remaining images. All of them will be placed under the logo.png main folder.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文