programing

Android 레이아웃 폴더에 하위 폴더를 포함할 수 있습니까?

lastcode 2023. 6. 26. 21:23
반응형

Android 레이아웃 폴더에 하위 폴더를 포함할 수 있습니까?

지금은 모든 XML 레이아웃 파일을 'res/layout' 폴더 안에 저장하고 있기 때문에 작은 프로젝트를 관리하는 것이 실현 가능하고 간단하지만, 크고 무거운 프로젝트의 경우에는 레이아웃 폴더 안에 계층 구조와 하위 폴더가 있어야 합니다.

예를 들어

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

같은 방법으로, 우리는 큰 애플리케이션을 위한 하위 폴더를 가지고 싶은데, 안드로이드 프로젝트 내에서 그렇게 할 수 있는 방법이 있습니까?

레이아웃 폴더 내에 layout-personal 및 layout_address 하위 폴더를 만들 수 있지만 R.layout을 사용하여 XML 레이아웃 파일에 액세스할 때가 되면 생성할 수 있습니다._____, 현재 메뉴 내에는 XML 레이아웃 팝업이 없습니다.

이 작업을 수행할 수 있습니다.gradle방법을 보여주는 데모 프로젝트를 만들었습니다.

이 방법은 Gradle의 기능을 사용하여 여러 리소스 폴더를 병합하고 res 폴더와 함께sourceSets블록으로 막다

컨테이너 리소스 폴더의 하위 리소스 폴더를 선언하기 전에 컨테이너 리소스 폴더를 선언할 수 없습니다.

는 아는입니다.sourceSets에서 합니다.build.gradle데모 파일입니다.하위 폴더가 먼저 선언됩니다.

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

nested resources picture

또한 실제 리소스 파일(pngs, xml 레이아웃 등)의 직접 상위 항목입니다.)는 여전히 사양과 일치해야 합니다.

대답은 아니오입니다.

저는 다음과 같은 내용이 담긴 이 책 Pro Android 2에 주목하고 싶습니다.

또한 리소스와 관련된 몇 가지 제약 사항에 주목할 필요가 있습니다.첫째, Android는 res 아래의 미리 정의된 폴더 내 파일의 선형 목록만 지원합니다.예를 들어 레이아웃 폴더(또는 res 아래의 다른 폴더) 아래에 중첩된 폴더를 지원하지 않습니다.

둘째, 자산 폴더와 원시 폴더 언더레스 사이에는 몇 가지 유사점이 있습니다.두 폴더 모두 원시 파일을 포함할 수 있지만 원시 파일은 리소스로 간주되고 자산 내 파일은 리소스로 간주되지 않습니다.

자산 폴더의 내용은 리소스로 간주되지 않으므로 폴더파일의 임의 계층을 폴더에 넣을 수 있습니다.

저는 단지 사람들이 어려움을 겪는 것에 대한 에스키스의 환상적인 대답에 덧붙이고 싶었습니다.(참고: 안타깝게도 이것은 '안드로이드' 보기가 아닌 '프로젝트' 보기 내의 개별 디렉토리로만 작동하고 표시됩니다.)

다음을 사용하여 테스트합니다.BuildToolsVersion = 23.0.0 Gradle 1.2.3 & 1.3.0

이것이 제가 이미 구축된 프로젝트를 수행하게 된 방법입니다.

  1. 레이아웃 디렉터리에서 모든 XML 파일을 복사하여 바탕 화면의 디렉터리나 백업용 디렉터리에 넣습니다.
  2. 전체 레이아웃 디렉토리를 삭제합니다(1단계부터 모든 것을 백업했는지 확인합니다!)
  3. res 디렉토리를 마우스 오른쪽 버튼으로 클릭하고 new > 디렉토리를 선택합니다.
  4. 이 새 디렉터리의 이름을 "레이아웃"으로 지정합니다.(이 디렉토리는 원하는 대로 사용할 수 있지만 나중에 제공되는 'fragment' 디렉토리나 'activity' 디렉토리는 아닙니다.)
  5. 새 "layouts" 디렉토리를 마우스 오른쪽 단추로 클릭하고 새 > 디렉토리를 선택합니다. (이 디렉토리는 'fragments' 및 'activities'와 같은 XML 파일 유형의 이름이 됩니다.)
  6. 'fragment' 또는 'activities' 디렉토리를 마우스 오른쪽 버튼으로 클릭하고(참고: 이 디렉토리가 'fragment' 또는 'activities'일 필요는 없음) 다시 한 번 new > 디렉토리를 선택하고 이 디렉토리의 이름을 "layout"으로 지정합니다.(참고: 이 이름은 '레이아웃'으로 지정해야 합니다!!매우 중요함).
  7. 바탕 화면에 만든 백업에서 원하는 XML 파일을 새 '레이아웃' 디렉터리 안에 넣습니다.
  8. 원하는 만큼의 사용자 정의 디렉토리에 대해 5 - 7단계를 반복합니다.
  9. 작업이 완료되면 모듈 그라데이션으로 이동합니다.파일을 빌드하고 다음과 같은 sourceSets 정의를 만듭니다.('src/main/res/layout' & 'src/main/res'가 항상 하위 2개인지 확인합니다!!!!아래에 표시된 것처럼).

    sourceSets {
        main {
            res.srcDirs =
                    [
                            'src/main/res/layouts/activities',
                            'src/main/res/layouts/fragments',
                            'src/main/res/layouts/content',
                            'src/main/res/layouts',
                            'src/main/res'
                    ]
        }
    }
    
  10. 이익 $$$$

하지만 정말로..이것이 제가 그것을 작동하게 한 방법입니다.궁금한 사람 있으면 알려주세요.제가 도와드릴 수 있습니다.

사진은 말보다 더 가치가 있습니다.

Directory Structure

가능하지 않지만 레이아웃 폴더가 이름별로 정렬됩니다.그래서 레이아웃 파일 이름 앞에 패키지 이름을 붙입니다.예: "구매" 및 "재생" 패키지의 경우:

buying_bought_tracks.xml
buying_buy_tracks.xml
playing_edit_playlist.xml
playing_play_playlist.xml
playing_show_playlists.xml

Android Studio용 Android File Group 플러그인을 사용합니다.하위 폴더를 만들 수는 없지만 다른 폴더에 있는 파일과 리소스를 표시할 수 있습니다.그리고 이것이 바로 제가 원했던 것입니다.

"Android File Grouping" 플러그인을 설치할 수 있는 방법은 다음과 같습니다.

Windows:

Android Studio -> 파일 -> 설정 -> 플러그인

Mac:

Android Studio -> Android Studio 탭(왼쪽 위) -> 기본 설정 -> 플러그인 -> JetBrains 플러그인 설치..

Mac의 경우 테스트할 수 있었고 플러그인을 검색할 수 없었습니다.그래서 저는 여기서 플러그인을 다운로드하여 사용했습니다.Install plugin from disk위의 설정에서 옵션을 클릭합니다.

작은 문제

이 질문에 대한 상위 답변에 따라 하위 폴더를 만들 수 있습니다.

그러나 프로젝트가 커질수록 다음과 같은 하위 폴더가 많아집니다.

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

큰 문제는 아니지만, 다음과 같습니다.

  • 목록이 너무 길어져서 예쁘지 않아요.
  • 은 당신의 변야니다를 .app/build.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()a relative path의론으로서relative path는 프로젝트의 루트에 상대적입니다.그래서 우리가 입력할 때"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
}

도움이 되길 바랍니다!

(하위 폴더가 허용되지 않는 경우) 이 문제에 대한 가장 우아한 해결책은 파일 이름 앞에 배치한 폴더의 이름을 추가하는 것입니다.예를 들어, 활동, 조각 또는 "장소"라는 일반 보기에 대한 레이아웃이 여러 개 있는 경우에는 places_my_layout_name으로 추가해야 합니다.적어도 이것은 IDE 내에서 더 쉽게 찾을 수 있는 방식으로 구성하는 문제를 해결합니다.가장 멋진 해결책은 아니지만 없는 것보다는 낫습니다.

Android Studio 및 Gradle을 사용하면 프로젝트에 여러 리소스 폴더를 만들 수 있습니다.레이아웃 파일뿐만 아니라 모든 종류의 리소스를 구성할 수 있습니다.

하위 폴더는 아니지만 응용프로그램의 일부가 분리될 수 있습니다.

구성은 다음과 같습니다.

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

설명서를 확인하십시오.

이제 "Android File Grouping"이라는 JetBrains 플러그인으로 쉽게 수행할 수 있습니다.

이 링크를 확인하십시오.

Android 파일 그룹화

enter image description here

제가 한 방법은 프로젝트의 실제 res 폴더와 동일한 수준으로 별도의 res 폴더를 생성하는 것이었고, 그러면 당신은 이것을 당신의 앱 build.gradle에서 사용할 수 있습니다.

android {
    //other stuff

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

example folder structure

그러면 당신의 새로운 res 폴더의 각 하위 폴더는 당신의 앱의 각 특정 화면과 관련된 것이 될 수 있고, 각 폴더는 그들만의 것을 가질 것입니다.layout/drawable/values정리된 상태를 유지하고 다른 답변처럼 수동으로 그라들 파일을 업데이트할 필요가 없습니다(새 리소스 폴더를 추가할 때마다 그라들 파일을 동기화하여 해당 리소스 폴더를 인식하고 xml 파일을 추가하기 전에 관련 하위 폴더를 추가하십시오).

폴더 계층을 단일 폴더로 변환하는 Bash 플랫 폴더 선택 스크립트

승인된 답변에서 방법을 사용하고 약간의 개선을 원하는 경우 다음과 같이 그라들 설정을 변경합니다.

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

따라서 폴더와 레이아웃을 더 추가할 경우 여기에 다시 와서 긴 원본 폴더 목록을 추가할 필요가 없습니다. 모든 폴더를 gradle에서 가져올 수 있습니다.

Linux 또는 Mac 박스에서 개발 중인 경우에는 레이아웃 파일에 대한 심볼릭 링크를 포함하는 하위 폴더를 만드는 것이 해결 방법입니다.-s와 함께 ln 명령을 사용합니다.

ln -s PATH_TO_YOUR_FILE

이 문제는 레이아웃 폴더에 여전히 모든 .xml 파일이 포함되어 있다는 것입니다.그러나 하위 폴더를 사용하여 선택할 수도 있습니다.그것은 당신이 원하는 것과 가장 가까운 것입니다.

Vista 이상을 사용하는 경우 Windows에서도 작동할 수 있다는 내용을 방금 읽었습니다. 게 .mklinkㅠㅠㅠㅠ 가 직접 한 적은 .구글로 검색해 보세요. 제가 직접 사용한 적은 없습니다.

또 다른 문제는 파일을 연 상태에서 다시 열려고 하면 플러그인이 NULL 포인터 예외를 발생시킨다는 것입니다.하지만 끊기지 않습니다.

여러 리소스 세트에 대한 모든 제안이 작동할 수 있지만 Android Studio Gradle 플러그인에 대한 현재 논리는 중첩된 리소스 세트에 대해 변경된 후 리소스 파일을 업데이트하지 않습니다.현재 구현에서는 startsWith()를 사용하여 리소스 디렉토리를 확인하려고 하므로 중첩된 디렉토리 구조(예: src/main/res/layout/layouts2 및 src/main/res/layouts/layouts_category2)는 src/layouts/main/layouts/layouts를 일관되게 선택하고 실제로 변경 사항을 업데이트하지 않습니다.결과적으로 매번 프로젝트를 다시 작성/정리해야 합니다.

저는 문제 해결을 돕기 위해 https://android-review.googlesource.com/ #/c/sla971/에 패치를 제출했습니다.

@eski의 탑답은 좋지만 코드가 우아하게 사용하기에는 부족하여 일반적으로 사용하기 위해 groovy 스크립트를 gradle로 작성하였습니다.모든 빌드 유형 및 제품 버전에 적용되며 레이아웃에 사용할 수 있을 뿐만 아니라 그리기 가능과 같은 다른 리소스 유형에 대한 하위 폴더를 추가할 수도 있습니다.여기 코드가 있습니다(입력하세요.android프로젝트 수준 Gradle 파일 블록):

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

연습은 어떻게 합니까?

를 들어, " ▁named다▁sub"라는 하위 폴더를 만들고 .activity위해서layout임의이 문추열가자에서 임의의 합니다.resDirs과 같은 layouts xml 을 xml 파일에 넣어야 .res\layouts\activity\layout\xxx.xml.

내가 이이지하라는 이름의 를 만들고 ,selectors위해서drawable임의이 문추열가자에서 임의의 합니다.resDirs과 같은 drawables을 그고나그수 xml 들니합에 .res\drawables\selectors\drawable\xxx.xml.

예: 다과같폴이름더)layouts그리고.drawables에 정의되어 있습니다.resDirs변수, 임의의 문자열일 수 있습니다.한 모든 예: 다과같사이하폴더위)activity또는selectors와 동일한 것으로 간주됩니다.res폴더를 누릅니다. ㅠㅠ.selectors는 폴더, 우는만합니다야들을 합니다.drawable로 폴더를 을 xml 파일로 합니다.drawable폴더, 그 후 그램들은 xml 파일을 일반적으로 그릴 수 있는 것으로 인식할 수 있습니다.

  • 1단계: 레이아웃을 마우스 오른쪽 버튼으로 클릭 - 탐색기에 표시
  • 2단계: 레이아웃 폴더를 열고 하위 폴더(layout_1, layout_2...)를 직접 만듭니다.
  • 3단계: 레이아웃 열기_1 폴더 레이아웃 만들기(참고: 필수 이름은 레이아웃), 레이아웃 열기_2 폴더 레이아웃 하위 디렉토리 만들기(참고: 필수 이름은 레이아웃)...
  • 4단계: layout_1 및 layout_2의 레이아웃 하위 디렉토리에 xml 파일을 복사합니다.
  • 5단계: buid.grade(모듈 앱)의 코드를 실행하고 지금 sync를 누릅니다.

sourceSets {
    main {
        res.srcDirs =
            [
                'src / main / res / layout / layout_1'
                'src / main / res / layout / layout_2',
                'src / main / res'
            ]
    }
}
  • 6단계: 요약: 위의 모든 단계는 폴더를 클러스터링하고 '프로젝트' 모드로 표시하는 데 도움이 되며 '안드로이드' 모드는 정상적으로 표시됩니다.
  • 그래서 접두사 이름을 지정하는 것이 클러스터링 폴더만큼 효과적일 수 있다고 생각합니다.

글쎄요, 짧게 대답하면 '아니오'하지만 당신은 분명히 여러 개를 가질 수 있습니다.res폴더.내 생각에, 그것은 당신이 할 수 있는 한 하위 폴더를 가질 수 있는 것에 가깝습니다.layout폴더를 누릅니다.방법은 다음과 같습니다.

에는 몇 단점이 . 경로를 . 는 새 를 상위답는단있다에 합니다. 새로운 레이아웃 경로를 추가해야 하고, 새로운 리소스를 배치해야 합니다.res\layouts폴대신 대신 합니다.res\values.

제가 작성한 몇 가지 답변을 종합하면 다음과 같습니다.

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

저는 http://alexzh.com/tutorials/how-to-store-layouts-in-different-folders-in-android-project/ 이라는 기사로 폴더를 만들었습니다.하위 폴더를 만들려면 다음 메뉴를 사용해야 합니다.New > Folder > Res Folder.

갱신하다

몇 주 후에 Android Studio에서 리소스 변경 사항을 인식하지 못했다는 것을 알게 되었습니다.그래서, 몇몇 이상한 벌레들이 나타납니다.예를 들어, 레이아웃에는 이전 크기, 여백이 계속 표시됩니다.AS가 새 XML 파일을 찾지 못하는 경우가 있습니다(특히 런타임 중).가끔은 섞이기도 합니다.view ids(다른 XML 파일에 대한 참조).를 눌러야 하는 경우가 많습니다.Build > Clean Project또는Build > Rebuild ProjectAndroid Studio에서 xml 레이아웃 파일을 변경한 후 Rebuild가 필요함을 읽습니다.

하위 디렉터리는 쉽게 가질 수 없지만 추가 리소스 폴더는 가질 수 있습니다.아무도 아직 언급하지 않았지만 기본 리소스 폴더를 유지하고 다음을 추가한 은 놀라운 일입니다.

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

모듈 내에서 플레이버, 플레이버 리소스(레이아웃, 값) 및 플레이버 리소스를 조합하기 위해 주의해야 할 주요 사항은 다음 두 가지입니다.

  1. 디추때가할에서 리소스 할 때res.srcDirs맛을 위해, 다른 모듈과 심지어는src/main/res동일한 모듈의 리소스 디렉터리도 추가됩니다.따라서 추가 ) .+=모든 기존 리소스를 새 할당으로 덮어쓰지 않도록 합니다.

  2. 어레이의 요소로 선언된 경로는 리소스 유형을 포함하는 경로입니다. 즉, 리소스 유형은 일반적으로 res 폴더에 포함되는 모든 하위 디렉터리(색상, 그리기 가능, 레이아웃, 값 등)입니다.res 폴더의 이름을 변경할 수 있습니다.

를 들어, " 예들어경사를다니용합로를▁path다니" 경로를 입니다."src/flavor/res/values/strings-ES"인 " 하만실계는하에디위렉가합있리다니어야터지층습▁has▁the다합▁have니▁to▁subdirectory▁the"를 가져야 합니다.values:

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

프레임워크는 유형별로 리소스를 정확하게 인식하므로 일반적으로 알려진 하위 디렉터리를 생략할 수 없습니다.

또한 모든 것들이strings.xml플레이버 안에 있는 파일은 리소스가 중복되지 않도록 유니언을 형성합니다.그 결과, 맛에 파일을 형성하는 이 결합은 모듈의 메인 앞에 더 높은 우선순위를 가집니다.

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

고려해 보십시오.strings-ES리소스 유형을 포함하는 사용자 정의 res 디렉터리입니다.

GL

언급URL : https://stackoverflow.com/questions/4930398/can-the-android-layout-folder-contain-subfolders

반응형