Android布局文件夹可以包含子文件夹吗?
现在,我将每个 XML 布局文件存储在“res/layout”文件夹中,因此管理小型项目是可行且简单的,但是当存在大型且繁重的项目时,则应该有一个层次结构和布局文件夹内需要的子文件夹。
例如,
layout
-- layout_personal
-- personal_detail.xml
-- personal_other.xml
--layout_address
-- address1.xml
-- address2.xml
像同样的方式,我们希望为大型应用程序创建子文件夹,那么有没有办法在Android项目中做到这一点?
我能够在布局文件夹内创建layout-personal和layout_address子文件夹,但是当需要使用 R.layout._______ 访问XML布局文件时,当时在布局文件夹内没有任何XML布局弹出窗口菜单。
Right now, I'm storing every XML layout file inside the 'res/layout' folder, so it is feasible and simple to manage small projects, but when there is a case of large and heavy projects, then there should be a hierarchy and sub-folders needed inside the layout folder.
for e.g.
layout
-- layout_personal
-- personal_detail.xml
-- personal_other.xml
--layout_address
-- address1.xml
-- address2.xml
Like the same way, we would like to have sub-folders for the large application, so is there any way to do so inside the Android project?
I am able to create layout-personal and layout_address sub-folders inside the layout folder, but when the time comes to access the XML layout file using R.layout._______ , at that time there is no any XML layout pop-up inside the menu.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(20)
您可以使用
gradle
来做到这一点。我制作了一个演示项目来展示如何操作。诀窍是使用 gradle 的功能合并多个资源文件夹,并在
sourceSets
块中设置 res 文件夹以及嵌套子文件夹。奇怪的是,在声明容器资源文件夹的子资源文件夹之前,您无法声明该文件夹。
下面是演示中
build.gradle
文件中的sourceSets
块。请注意,首先声明子文件夹。另外,实际资源文件(png、xml 布局等)的直接父级仍然需要符合规范。
You CAN do this with
gradle
. I've made a demo project showing how.The trick is to use gradle's ability to merge multiple resource folders, and set the res folder as well as the nested subfolders in the
sourceSets
block.The quirk is that you can't declare a container resource folder before you declare that folder's child resource folders.
Below is the
sourceSets
block from thebuild.gradle
file from the demo. Notice that the subfolders are declared first.Also, the direct parent of your actual resource files (pngs, xml layouts, etc..) does still need to correspond with the specification.
答案是否定的。
我想提请您注意这本书Pro Android 2,其中指出:
The answer is no.
I would like to draw your attention towards this book Pro Android 2 that states:
我只是想补充 eskis 为遇到麻烦的人提供的精彩答案。 (注意:这只能工作,并且看起来像“项目”视图中的单独目录,不幸的是,而不是“android”视图中的目录。)
使用以下内容进行了测试。
构建工具版本 = 23.0.0
gradle 1.2.3 & 1.3.0
这就是我如何让我的项目与已经构建的项目一起工作。
完成后,进入模块 gradle.build 文件并创建一个像这样的 sourceSets 定义...(确保 'src/main/res/layouts' 和 'src/main/res' 始终是下面两个!!!就像我下面展示的那样)。
利润$$$$
但说真的..这就是我让它工作的方式。如果有人有任何疑问请告诉我..我可以尽力提供帮助。
图片比文字更有价值。
I just wanted to add onto eskis' fantastic answer for people having trouble. (Note: This will only work and look like separate directories inside the 'project' view, not the 'android' view unfortunately.)
Tested with the following.
BuildToolsVersion = 23.0.0
gradle 1.2.3 & 1.3.0
This is how I got mine to work with an already built project.
Once this is complete, go into your modules gradle.build file and create a sourceSets definition like this...(Make sure 'src/main/res/layouts' & 'src/main/res' are always the bottom two!!!! Like I am showing below).
Profit $$$$
But seriously.. this is how I got it to work. Let me know if anyone has any questions.. I can try to help.
Pictures are worth more than words.
不可能,但布局文件夹按名称排序。因此,我在布局文件名前面加上我的包名称。例如,对于“购买”和“玩”两个包:
Not possible, but the layout folder is sorted by name. So, I prepend the layout file names with my package names. E.g. for the two packages "buying" and "playing":
我使用 Android Studio 的 Android 文件分组 插件。它实际上不允许您创建子-文件夹,但它可以显示您的文件和资源,因为它们位于不同的文件夹中。这正是我想要的。
安装“Android文件分组”插件
您可以通过Windows
苹果:
对于 Mac,我能够测试它,但无法搜索该插件。因此,我从此处下载了该插件,并使用了
从磁盘安装插件<上述设置中的 /code> 选项。
I use Android File Grouping plugin for Android Studio.It doesn't really allows you to create sub-folders, but it can DISPLAY your files and resources AS they are in different folders. And this is exactly what I wanted.
You can install "Android File Grouping" plugin by
Windows:
Mac:
For Mac, I was able to test it and was not able to search for the plugin. So I downloaded the plugin from here and used the
Install plugin from disk
option from the above setting.小问题
我可以通过遵循此问题的最佳答案来实现子文件夹。
然而,随着项目变得越来越大,您将拥有许多子文件夹:
不是一个大问题,但是:
app/build.gradle
。改进
因此,我编写了一个简单的 Groovy 方法来获取所有嵌套文件夹:
将此方法粘贴到
app/build.gradle
中的android {...}
块之外。如何使用
对于这样的结构:
像这样使用:
如果您有这样的结构:
您将像这样使用它:
说明
getLayoutList()
采用相对路径
作为参数。相对路径
是相对于项目根目录的。因此,当我们输入"app/src/main/res/layouts/"
时,它将以数组形式返回所有子文件夹的名称,这与以下内容完全相同:这是带有注释的脚本理解:
希望有帮助!
Small Problem
I am able to achieve subfolders by following the top answer to this question.
However, as the project grows bigger, you will have many sub-folders:
Not a big problem, but:
app/build.gradle
everytime you add a new folder.Improvement
So I wrote a simple Groovy method to grab all nested folders:
Paste this method outside of the
android {...}
block in yourapp/build.gradle
.How to use
For a structure like this:
Use it like this:
If you have a structure like this:
You will use it like this:
Explanation
getLayoutList()
takesa relative path
as an argument. Therelative path
is relative to the root of the project. So when we input"app/src/main/res/layouts/"
, it will return all the subfolders' name as an array, which will be exactly the same as:Here's the script with comments for understanding:
Hope it helps!
我认为解决这个问题的最优雅的解决方案(假设不允许使用子文件夹)是在文件名前面加上您将其放置在其中的文件夹的名称。例如,如果您有一堆 Activity、Fragment 的布局,或者只是称为“places”的一般视图,那么您应该在其前面添加places_my_layout_name。至少这解决了以更容易在 IDE 中找到它们的方式组织它们的问题。这不是最棒的解决方案,但总比没有好。
I think the most elegant solution to this problem (given that subfolders are not allowed) is to prepend the file names with the name of the folder you would have placed it inside of. For example, if you have a bunch of layouts for an Activity, Fragment, or just general view called "places" then you should just prepend it with places_my_layout_name. At least this solves the problem of organizing them in a way that they are easier to find within the IDE. It's not the most awesome solution, but it's better than nothing.
现在,借助 Android Studio 和 Gradle,您可以在项目中拥有多个资源文件夹。不仅可以组织布局文件,还可以组织任何类型的资源。
它不完全是一个子文件夹,但可能分隔应用程序的各个部分。
配置是这样的:
查看文档。
Now with Android Studio and Gradle, you can have multiple resource folders in your project. Allowing to organize not only your layout files but any kind of resources.
It's not exactly a sub-folder, but may separte parts of your application.
The configuration is like this:
Check the documentation.
现在我们可以轻松地使用名为“Android File Grouping”的 JetBrains 插件
来查看此链接
Android 文件分组
Now we can easily do with JetBrains plugin called "Android File Grouping"
check out this link
Android File Grouping
我这样做的一种方法是创建一个单独的 res 文件夹,与项目中的实际 res 文件夹处于同一级别,然后您可以在应用程序 build.gradle
然后是新 res 文件夹的每个子文件夹可以是与每个特定屏幕或应用程序中的某些内容相关的内容,每个文件夹都有自己的
layout
/drawable
/values
等来保存内容组织起来,您不必像其他一些答案所要求的那样手动更新 gradle 文件(每次添加新资源文件夹时同步您的 gradle 以便它知道它,并确保在添加 xml 文件之前添加相关子文件夹)。A way i did it was to create a separate res folder at the same level as the actual res folder in your project, then you can use this in your apps build.gradle
then each subfolder of your new res folder can be something relating to each particular screen or something in your app, and each folder will have their own
layout
/drawable
/values
etc keeping things organised and you dont have to update the gradle file manually like some of these other answers require (Just sync your gradle each time you add a new resource folder so it knows about it, and make sure to add the relevant subfolders before adding your xml files).检查将文件夹层次结构转换为单个文件夹的 Bash 展平文件夹脚本
Check Bash Flatten Folder script that converts folder hierarchy to a single folder
如果您使用已批准答案中的方法,并且想要对其进行一些改进,请像这样更改 gradle 设置:
因此,如果您添加更多文件夹和布局,则无需返回此处并附加一长串列表源文件夹,让 gradle 为您获取所有文件夹。
If you use the method in the approved answer, and want to improve it on a bit, then change the gradle setting like this:
So if you add more folders and layouts, you don't need to come back here and append a long list of source folders, let gradle get all the folders for you.
如果您正在 Linux 或 Mac 上进行开发,解决方法是创建包含布局文件符号链接的子文件夹。只需使用带有 -s 的 ln 命令
问题是,您的布局文件夹仍然包含所有 .xml 文件。但是您可以通过使用子文件夹来选择它们。这是最接近您想要拥有的东西。
我刚刚读到,如果您使用的是 Vista 或更高版本,这也可能适用于 Windows。有这个
mklink
命令。 google了一下,自己没用过。另一个问题是,如果您打开了文件并尝试再次打开它,插件会抛出空指针异常。但它不会挂断。
If you are developing on a linux or a mac box, a workaround would be, to create subfolders which include symbolic links to your layoutfiles. Just use the ln command with -s
The Problem with this is, that your Layout folder still contains all the .xml files. But you could although select them by using the sub-folders. It's the closest thing, to what you would like to have.
I just read, that this might work with Windows, too if you are using Vista or later. There is this
mklink
command. Just google it, have never used it myself.Another problem is, if you have the file opened and try to open it again out the plugin throws a NULL Pointer Exception. But it does not hang up.
虽然针对多个资源集的所有建议都可能有效,但问题是 Android Studio Gradle 插件的当前逻辑在资源文件针对嵌套资源集更改后不会更新。当前的实现尝试使用startsWith()检查资源目录,因此嵌套的目录结构(即src/main/res/layout/layouts和src/main/res/layout/layouts_category2)将选择src/main/res /layout/layouts 保持一致,并且从不实际更新更改。最终结果是您每次都必须重建/清理项目。
我在 https://android-review.googlesource.com/#/c 提交了补丁/157971/ 尝试帮助解决问题。
While all the proposals for multiple resource sets may work, the problem is that the current logic for the Android Studio Gradle plug-in will not update the resource files after they have changed for nested resource sets. The current implementation attempts to check the resource directories using startsWith(), so a directory structure that is nested (i.e. src/main/res/layout/layouts and src/main/res/layout/layouts_category2) will choose src/main/res/layout/layouts consistently and never actually update the changes. The end result is that you have to rebuild/clean the project each time.
I submitted a patch at https://android-review.googlesource.com/#/c/157971/ to try to help resolve things.
@eski 的最佳答案很好,但是代码使用起来并不优雅,所以我在 gradle 中编写了一个 groovy 脚本以供一般使用。它适用于所有构建类型和产品风格,不仅可以用于布局,您还可以为任何其他资源类型(例如可绘制资源)添加子文件夹。代码如下(放在项目级gradle文件的
android
块中):实际中怎么做?
例如,我想为
layout
创建名为activity
的子文件夹,在resDirs
变量中添加任意名称的字符串,例如layouts< /code>,那么布局xml文件应该放在
res\layouts\activity\layout\xxx.xml
中。如果我想为
drawable
创建名为selectors
的子文件夹,请在resDirs
变量中添加任意名称的字符串,例如drawables
>,那么drawable xml文件应该放在res\drawables\selectors\drawable\xxx.xml
中。layouts
和drawables
等文件夹名称定义在resDirs
变量中,可以是任何字符串。您创建的所有子文件夹(例如
activity
或selectors
)都被视为与res
文件夹相同。所以在selectors
文件夹中,我们必须另外创建drawable
文件夹,并将xml文件放入drawable
文件夹中,之后gradle才能将xml文件识别为drawable通常情况下。The top answer by @eski is good, but the code is not elegant to use, so I wrote a groovy script in gradle for general use. It's applied to all build type and product flavor and not only can be use for layout, you can also add subfolder for any other resources type such as drawable. Here is the code(put it in
android
block of project-level gradle file):How to do in practice?
For example, I want to create subfolder named
activity
forlayout
, add a string by any name inresDirs
variable such aslayouts
, then the layout xml file should be put inres\layouts\activity\layout\xxx.xml
.If I want to create subfolder named
selectors
fordrawable
, add a string by any name inresDirs
variable such asdrawables
, then the drawable xml file should be put inres\drawables\selectors\drawable\xxx.xml
.The folder name such as
layouts
anddrawables
is defined inresDirs
variable, it can be any string.All subfolder created by you such as
activity
orselectors
are regarded as the same asres
folder. So inselectors
folder, we must createdrawable
folder additionally and put xml files indrawable
folder, after that gradle can recognize the xml files as drawable normally.不能有子目录(很容易),但您可以有其他资源文件夹。令人惊讶的是没有人提到它,但要保留默认资源文件夹,并添加更多内容:
Cannot have subdirectories (easily) but you can have additional resource folders. Surprised no one mentioned it already, but to keep the default resource folders, and add some more:
嗯,简短的回答是否定的。但您绝对可以拥有多个
res
文件夹。我认为,这与layout
文件夹的子文件夹是最接近的。 这是具体操作方法。Well, the short answer is no. But you definitely can have multiple
res
folders. That, I think, is as close as you can get to having subfolders for thelayout
folder. Here's how you do it.最佳答案有几个缺点:您必须添加新的布局路径,AS 将新资源放置到
res\layouts
文件夹而不是res\values
中。结合我写的类似的几个答案:
我用这篇文章制作了文件夹: http://alexzh.com/tutorials/how-to-store-layouts-in- Different-folders-in-android-project/。为了创建子文件夹,您应该使用此菜单:“新建”>“子文件夹”。文件夹>资源文件夹。
更新
几周后,我发现Android Studio 没有注意到资源的变化。因此,一些奇怪的错误出现了。例如,布局继续显示旧的尺寸、边距。有时 AS 找不到新的 XML 文件(尤其是在运行时)。有时它会混合
视图 ID
(对另一个 XML 文件的引用)。通常需要按Build > 。清理项目
或构建>重建项目
。阅读 在 Android Studio 中更改 xml 布局文件后需要重新构建< /a>.Top answers have several disadvantages: you have to add new layout paths, AS places new resources to
res\layouts
folder instead ofres\values
.Combining several answers I wrote similar:
I made folders with this article: http://alexzh.com/tutorials/how-to-store-layouts-in-different-folders-in-android-project/. In order to create subfolders you should use this menu: New > Folder > Res Folder.
UPDATE
After a couple of weeks I found that changes in resources are not noticed by Android Studio. So, some weird bugs appear. For instance, layouts continue to show old sizes, margins. Sometimes AS doesn't find new XML-files (especially during run-time). Sometimes it mixes
view id
s (references to another XML-file). It's often required to pressBuild > Clean Project
orBuild > Rebuild Project
. Read Rebuild required after changing xml layout files in Android Studio.在模块内,要拥有风味、风味资源(布局、值)和风味资源资源的组合,需要记住的主要事情有两点:
在
res.srcDirs 中添加资源目录时+=
) 非常重要,以免新分配覆盖所有现有资源。声明为数组元素的路径是包含资源类型的路径,即资源类型是 res 文件夹通常包含的所有子目录,例如 颜色、drawable、布局、值等。res文件夹的名称可以更改。
一个例子是使用路径
“src/flavor/res/values/strings-ES”
,但注意实践层次结构必须具有子目录values
:框架按类型精确识别资源,这就是为什么通常已知的子目录不能被省略。
另请记住,风味内的所有
strings.xml
文件将形成一个联合,以便资源无法重复。反过来,在风味中形成文件的联合在模块的主文件之前具有更高的优先级。将 string-ES 目录视为包含资源类型的自定义资源。
GL
Within a module, to have a combination of flavors, flavor resources (layout, values) and flavors resource resources, the main thing to keep in mind are two things:
When adding resource directories in
res.srcDirs
for flavor, keep in mind that in other modules and even insrc/main/res
of the same module, resource directories are also added. Hence, the importance of using an add-on assignment (+=
) so as not to overwrite all existing resources with the new assignment.The path that is declared as an element of the array is the one that contains the resource types, that is, the resource types are all the subdirectories that a res folder contains normally such as color, drawable, layout, values, etc. The name of the res folder can be changed.
An example would be to use the path
"src/flavor/res/values/strings-ES"
but observe that the practice hierarchy has to have the subdirectoryvalues
:The framework recognizes resources precisely by type, that is why normally known subdirectories cannot be omitted.
Also keep in mind that all the
strings.xml
files that are inside the flavor would form a union so that resources cannot be duplicated. And in turn this union that forms a file in the flavor has a higher order of precedence before the main of the module.Consider the
strings-ES
directory as a custom-res which contains the resource types.GL