Android可绘制目录可以包含子目录吗?

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

我想知道在可绘制目录中创建子目录是否显式不允许。

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

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

我可以引用金枪鱼沙拉三明治的图片@drawable/三明治/tunaOnRye吗

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

165747 次浏览

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

您所显示的目录布局将导致所有图像都不可用。

从我自己的实验来看,在res/drawable文件夹中有一个包含任何项目的子文件夹,将导致资源编译器失败——阻止R.java文件正确生成。

是的-它确实很糟糕:)但是你可以使用资产文件夹,并在那里有子目录,以这种方式加载图像。

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

显然,这只能用于当你的目标API级别高于res/layout-v?你在吸毒。

另外,注意Android 1.5和1.6的bug。 # EYZ0。< / p >

我使用的解决方法(Android本身似乎更喜欢)基本上是用下划线代替正斜杠,所以你的结构看起来像这样:

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

这种方法要求您在命名时一丝不差,并且不会使文件本身变得更容易(如果您决定饮料和三明治真的都应该是“food”,那么您必须进行大规模重命名,而不是简单地将它们移动到目录中);但是与相同的文件夹结构相比,您的编程逻辑的复杂性并不会严重影响

这种情况确实很糟糕。Android是一个优秀和糟糕设计决策的混合体。我们只能希望后一部分能尽快被淘汰:)

使用资产文件夹。

示例代码:

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


image = BitmapFactory.decodeStream(is);

我喜欢使用一个简单的脚本来将设计人员提供的有组织的目录结构平铺成可以用来生成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

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

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

这并不像能够创建文件夹那么简单,但这有助于保持事情的理智……

#!/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?("/")
}

这是不完美的方法。你必须以同样的方式实现,即显示在这里

还可以通过使用的代码调用文件夹下的图像

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


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

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

更多细节可以在这里找到,请随意fork和发送拉请求:

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

enter image description here

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

https://stackoverflow.com/a/22426467/618419 < a href = " https://stackoverflow.com/a/22426467/618419 " > < / >

选中将文件夹层次结构转换为单个文件夹的Bash Flatten Folder脚本

/ < p >资产 您可以使用它来存储原始资产文件。保存在这里的文件将按原样编译为.apk文件,并保留原始文件名。您可以以与使用uri的典型文件系统相同的方式导航此目录,并使用AssetManager将文件作为字节流读取。例如,这是纹理和游戏数据的好位置。 # EYZ0 < / p >

在android studio和gradle中,你可以有多个源导演,这将允许你分离资源。例如:

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

然而,名称不能冲突,这意味着你仍然需要有名称,如三明治_tunaonrye,但你将能够有一个单独的部分,为所有的三明治。

这允许你存储你的资源在不同的结构(有用的自动生成的内容,如actionbargenerator)

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

在"配置结构"一段中

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

实际上,在Android Studio上这是可能的。你可以有嵌套资源,如这里<强> < / >强所示:

enter image description here

还有一个插件可以对资源这里<强> < / >强进行分组。

但我建议避免这样做。

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

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

在main中创建一个文件夹。 如:“res_notification_btn”< / p >

并创建树形文件夹。比如" drawable "或" layout "

然后在build中。Gradle '添加这个

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

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

resVector
-drawable
-layout
-color

之后你所需要做的就是添加

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

到你的build.gradle文件(在android { })。

  1. 右键单击Drawable
  2. 选择“新建——>目录”
  3. 输入目录名称。例如:logo.png(默认情况下位置已经显示可绘制文件夹)
  4. 将图像直接复制粘贴到可绘制文件夹中。在粘贴时,您可以选择mdpi/xhdpi/xxhdpi等从列表中的每个图像。选择适当的选项并输入映像的名称。确保名称与目录名称相同,即logo.png
  5. 对其余图像执行相同的操作。所有这些都将放在logo.png主文件夹下。

有可能有多个可绘制的文件夹,有一个额外的文件夹平行于'res'和一个子目录'drawable',然后添加以下到gradle:

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

用gradle 6.5.1测试

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

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

Example of setup in Xamarin

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

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

Xamarin的。Android,视觉编辑器将无法识别图像,并将显示错误“此资源URL无法解析”;但是项目将被构建,图像将在运行时可见。

编辑器错误 # EYZ0 < / p >