现在,我在'res/layout'文件夹内存储每个XML布局文件,因此管理小型项目是可行和简单的,但当有大型和繁重的项目的情况下,那么应该有一个层次结构和子文件夹内需要的布局文件夹。

如。

layout
-- layout_personal
   -- personal_detail.xml
   -- personal_other.xml
--layout_address
  -- address1.xml
  -- address2.xml

同样,我们希望大型应用程序有子文件夹,那么在Android项目中有办法做到这一点吗?

我能够在布局文件夹内创建layout-personal和layout_address子文件夹,但当需要使用R.layout访问XML布局文件时。_______,当时在菜单中没有任何XML布局弹出。


当前回答

第一步:在资源管理器中右键单击布局-显示 步骤2:打开布局文件夹并直接创建子文件夹:layout_1, layout_2… 步骤3:打开layout_1创建文件夹布局(注意:必选名称为布局),打开layout_2文件夹创建文件夹布局子目录(注意:必选名称为布局)… 步骤4:将xml文件复制到layout_1和layout_2的布局子目录中 步骤5:运行build中的代码。Grade(模块应用),现在点击同步:


sourceSets {
    main {
        res.srcDirs =
            [
                'src / main / res / layout / layout_1'
                'src / main / res / layout / layout_2',
                'src / main / res'
            ]
    }
}

第6步:总结:以上所有步骤将只帮助集群文件夹和显示在“项目”模式,而“android”模式将正常显示。 所以我认为命名前缀可能和集群文件夹一样有效。

其他回答

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.

我在https://android-review.googlesource.com/#/c/157971/上提交了一个补丁,试图帮助解决问题。

你可以用gradle做到这一点。我做了一个演示项目来展示如何做到这一点。

诀窍是使用gradle的能力来合并多个资源文件夹,并设置res文件夹以及sourceSets块中的嵌套子文件夹。

奇怪的是,在声明容器资源文件夹的子资源文件夹之前,您不能声明该文件夹。

下面是构建中的sourceSets块。演示中的Gradle文件。注意,先声明子文件夹。

sourceSets {
    main {
        res.srcDirs = [
            'src/main/res/layouts/layouts_category2',
            'src/main/res/layouts',
            'src/main/res'
        ]
    }
}

另外,实际资源文件(png、xml布局等)的直接父文件仍然需要与规范相对应。

小问题

我能够通过遵循这个问题的顶部答案来实现子文件夹。

然而,随着项目越来越大,你会有很多子文件夹:

sourceSets {
    main {
        res.srcDirs = [
            'src/main/res/layouts/somethingA',
            'src/main/res/layouts/somethingB',
            'src/main/res/layouts/somethingC',
            'src/main/res/layouts/somethingD',
            'src/main/res/layouts/somethingE',
            'src/main/res/layouts/somethingF',
            'src/main/res/layouts/somethingG',
            'src/main/res/layouts/somethingH',
            'src/main/res/layouts/...many more',
            'src/main/res'
        ]
    }
}

不是什么大问题,但是:

当清单变得很长时,它就不好看了。 你必须改变你的应用/构建。每次添加新文件夹时Gradle。


改进

所以我写了一个简单的Groovy方法来抓取所有嵌套文件夹:

def getLayoutList(path) {
    File file = new File(path)
    def throwAway = file.path.split("/")[0]
    def newPath = file.path.substring(throwAway.length() + 1)
    def array = file.list().collect {
        "${newPath}/${it}"
    }
    array.push("src/main/res");
    return array
}

将此方法粘贴到android{…}块在你的app/build.gradle。


如何使用

对于这样的结构:

<project root>
├── app <---------- TAKE NOTE
├── build
├── build.gradle
├── gradle
├── gradle.properties
├── gradlew
├── gradlew.bat
├── local.properties
└── settings.gradle

像这样使用它:

android {
    sourceSets {
        main {
            res.srcDirs = getLayoutList("app/src/main/res/layouts/")
        }
    }
}

如果你有一个这样的结构:

<project root>
├── my_special_app_name <---------- TAKE NOTE
├── build
├── build.gradle
├── gradle
├── gradle.properties
├── gradlew
├── gradlew.bat
├── local.properties
└── settings.gradle

你可以这样使用它:

android {
    sourceSets {
        main {
            res.srcDirs = getLayoutList("my_special_app_name/src/main/res/layouts/")
        }
    }
}

解释

getLayoutList()接受一个相对路径作为参数。相对路径相对于项目的根路径。所以当我们输入"app/src/main/res/layouts/"时,它会以数组的形式返回所有子文件夹的名称,这将与:

[
    'src/main/res/layouts/somethingA',
    'src/main/res/layouts/somethingB',
    'src/main/res/layouts/somethingC',
    'src/main/res/layouts/somethingD',
    'src/main/res/layouts/somethingE',
    'src/main/res/layouts/somethingF',
    'src/main/res/layouts/somethingG',
    'src/main/res/layouts/somethingH',
    'src/main/res/layouts/...many more',
    'src/main/res'
]

下面是带有注释的脚本,便于理解:

def getLayoutList(path) {
    // let's say path = "app/src/main/res/layouts/
    File file = new File(path)

    def throwAway = file.path.split("/")[0]
    // throwAway = 'app'

    def newPath = file.path.substring(throwAway.length() + 1) // +1 is for '/'
    // newPath = src/main/res/layouts/

    def array = file.list().collect {
        // println "filename: ${it}" // uncomment for debugging
        "${newPath}/${it}"
    }

    array.push("src/main/res");
    // println "result: ${array}" // uncomment for debugging

    return array
}

希望能有所帮助!

答案是否定的。

我想提请您注意这本书Pro Android 2,它指出:

It is also worth noting a few constraints regarding resources. First, Android supports only a linear list of files within the predefined folders under res. For example, it does not support nested folders under the layout folder (or the other folders under res). Second, there are some similarities between the assets folder and the raw folder under res. Both folders can contain raw files, but the files within raw are considered resources and the files within assets are not. Note that because the contents of the assets folder are not considered resources, you can put an arbitrary hierarchy of folders and files within it.

我这样做的一种方式是在你的项目中创建一个与实际res文件夹相同级别的单独的res文件夹,然后你可以在你的应用程序build.gradle中使用这个

android {
    //other stuff

    sourceSets {
        main.res.srcDirs = ['src/main/res', file('src/main/layouts').listFiles()]
    }
}

然后每个新res文件夹的子文件夹可以一些有关每个特定屏幕或一些在你的应用程序,和每个文件夹都有自己的布局/可拉的价值观等保持事物的组织和你不必须手动更新gradle文件和其他一些答案要求(同步你gradle每次添加一个新的资源文件夹,所以它知道它,并确保添加相关的子文件夹之前添加xml文件)。