Can the Android layout folder contain subfolders?

前端 未结 20 2821
暗喜
暗喜 2020-11-22 03:10

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

20条回答
  •  轮回少年
    2020-11-22 04:10

    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:

    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'
                ]
        }
    }
    

    Not a big problem, but:

    • it's not pretty as the list become very long.
    • you have to change your app/build.gradle everytime you add a new folder.

    Improvement

    So I wrote a simple Groovy method to grab all nested folders:

    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
    }
    

    Paste this method outside of the android {...} block in your app/build.gradle.


    How to use

    For a structure like this:

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

    Use it like this:

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

    If you have a structure like this:

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

    You will use it like this:

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

    Explanation

    getLayoutList() takes a relative path as an argument. The relative 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:

                [
                        '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'
                ]
    

    Here's the script with comments for understanding:

    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
    }
    

    Hope it helps!

提交回复
热议问题