Can the Android layout folder contain subfolders?

前端 未结 20 2611
暗喜
暗喜 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 03:49

    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 the build.gradle file from the demo. Notice that the subfolders are declared first.

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

    nested resources picture

    Also, the direct parent of your actual resource files (pngs, xml layouts, etc..) does still need to correspond with the specification.

    0 讨论(0)
  • 2020-11-22 03:50

    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":

    buying_bought_tracks.xml
    buying_buy_tracks.xml
    playing_edit_playlist.xml
    playing_play_playlist.xml
    playing_show_playlists.xml
    
    0 讨论(0)
  • 2020-11-22 03:52

    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.

    0 讨论(0)
  • 2020-11-22 03:53

    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

    ln -s PATH_TO_YOUR_FILE

    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.

    0 讨论(0)
  • 2020-11-22 03:54

    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:

    1. 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.

    2. 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 subdirectory values:

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

    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.

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

    Consider the strings-ES directory as a custom-res which contains the resource types.

    GL

    0 讨论(0)
  • 2020-11-22 03:55

    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):

    sourceSets.each {
        def rootResDir = it.res.srcDirs[0]
        def getSubDirs = { dirName ->
            def layoutsDir = new File(rootResDir, dirName)
            def subLayoutDirs = []
            if (layoutsDir.exists()) {
                layoutsDir.eachDir {
                    subLayoutDirs.add it
                }
            }
            return subLayoutDirs
        }
        def resDirs = [
                "anims",
                "colors",
                "drawables",
                "drawables-hdpi",
                "drawables-mdpi",
                "drawables-xhdpi",
                "drawables-xxhdpi",
                "layouts",
                "valuess",
        ]
        def srcDirs = resDirs.collect {
            getSubDirs(it)
        }
        it.res.srcDirs = [srcDirs, rootResDir]
    }
    

    How to do in practice?

    For example, I want to create subfolder named activity for layout, add a string by any name in resDirs variable such as layouts, then the layout xml file should be put in res\layouts\activity\layout\xxx.xml.

    If I want to create subfolder named selectors for drawable, add a string by any name in resDirs variable such as drawables, then the drawable xml file should be put in res\drawables\selectors\drawable\xxx.xml.

    The folder name such as layouts and drawables is defined in resDirs variable, it can be any string. All subfolder created by you such as activity or selectors are regarded as the same as res folder. So in selectors folder, we must create drawable folder additionally and put xml files in drawable folder, after that gradle can recognize the xml files as drawable normally.

    0 讨论(0)
提交回复
热议问题