现在,我在'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布局弹出。


当前回答

小问题

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

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

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
}

希望能有所帮助!

其他回答

简而言之,答案是否定的。但你肯定可以有多个分辨率文件夹。我认为这是最接近布局文件夹的子文件夹了。你可以这样做。

在一个模块中,要拥有风味、风味资源(布局、值)和风味资源的组合,主要要记住两件事:

When adding resource directories in res.srcDirs for flavor, keep in mind that in other modules and even in src/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.

一个例子是使用路径"src/flavor/res/values/strings-ES",但是注意到实践层次结构必须有子目录值:

├── module 
   ├── flavor
      ├── res
         ├── values
            ├── strings-ES
               ├── values
                  ├── strings.xml
               ├── strings.xml
 

该框架精确地根据类型识别资源,这就是为什么通常已知的子目录不能被省略。

还要记住,flavor中的所有strings.xml文件将形成一个联合,这样资源就不能被复制。反过来,这个组成该类型文件的联合在模块的主文件之前具有更高的优先级。

flavor {
        res.srcDirs += [
            "src/flavor/res/values/strings-ES"
        ]
}

将strings-ES目录视为包含资源类型的定制资源。

GL

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

android {
    //other stuff

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

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

不能有子目录(很容易),但可以有额外的资源文件夹。很惊讶没有人提到它,但是保留默认的资源文件夹,并添加更多:

    sourceSets {
        main.res.srcDirs += ['src/main/java/XYZ/ABC']
    }

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.