โฟลเดอร์เค้าโครง Android สามารถมีโฟลเดอร์ย่อยได้หรือไม่?


551

ตอนนี้ฉันกำลังจัดเก็บไฟล์ xml ทุกรูปแบบไว้ในres/layoutโฟลเดอร์ดังนั้นจึงเป็นไปได้และง่ายต่อการจัดการโครงการขนาดเล็ก แต่เมื่อมีกรณีของโครงการขนาดใหญ่และหนักแล้วควรมีลำดับชั้นและโฟลเดอร์ย่อยที่จำเป็นภายใน โฟลเดอร์เค้าโครง

สำหรับเช่น

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

เช่นเดียวกับที่เราต้องการให้มีโฟลเดอร์ย่อยสำหรับแอพพลิเคชั่นขนาดใหญ่ดังนั้นจะมีวิธีการอย่างไรในโครงการ Android?

ฉันสามารถสร้างโฟลเดอร์ย่อย layout-personal และ layout_address ภายในโฟลเดอร์ layout ได้ แต่เมื่อถึงเวลาที่จะเข้าถึงไฟล์เลย์เอาท์ xml โดยใช้ R.layout ._______ ในเวลานั้นไม่มีเลย์เอาต์ xml แบบผุดขึ้นข้างใน เมนู.



ฉันคิดว่าลิงก์นี้อาจช่วยคุณในรายละเอียด blog.mindorks.com/…
Dilip Poudel

คำตอบ:


475

คุณสามารถทำได้ด้วย gradle ฉันได้ทำโปรเจ็กต์สาธิตที่แสดงว่า

เคล็ดลับคือการใช้ความสามารถของ gradle ในการรวมหลาย ๆ โฟลเดอร์ทรัพยากรและตั้งค่าโฟลเดอร์ res รวมถึงโฟลเดอร์ย่อยที่ซ้อนกันในบล็อก sourceSets

สิ่งแปลกประหลาดคือคุณไม่สามารถประกาศโฟลเดอร์คอนเทนเนอร์ทรัพยากรก่อนที่คุณจะประกาศโฟลเดอร์ย่อยของโฟลเดอร์นั้น

ด้านล่างนี้คือบล็อก sourceSets จากไฟล์ build.gradle จากการสาธิต ขอให้สังเกตว่ามีการประกาศโฟลเดอร์ย่อยก่อน

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

รูปภาพทรัพยากรซ้อนกัน

นอกจากนี้ผู้ปกครองโดยตรงของไฟล์ของคุณที่เกิดขึ้นจริงทรัพยากร (PNGs รูปแบบ XML, ฯลฯ .. ) ไม่ยังคงต้องสอดคล้องกับข้อกำหนด


6
เป็นไปได้หรือไม่ที่จะทำเช่นนี้กับโฟลเดอร์ drawable? ฉันเพิ่งลองโดยไม่มีโชคแม้จะคำนึงถึงการประกาศคำสั่ง
เทรเวอร์ -e

7
ดี! โปรดจำไว้ว่าคุณใช้ประโยชน์จากความสามารถของ gradle ในการผสานโฟลเดอร์ทรัพยากรและมันจะเข้าท่า
eski

5
ชื่อไฟล์ในโฟลเดอร์จะต้องไม่ซ้ำกันและในรหัสที่คุณต้องรู้ว่าเช่นR.layout.list_itemมาจากmoviesหรือcinemasโฟลเดอร์ดังนั้นการตั้งชื่อแบนยังคงใช้
TWiStErRob

5
แต่น่าเสียดายที่ไม่ได้ทำงานให้ฉันด้วยและbuild:gradle:0.14.4 buildToolsVersion "21.1.1"
Kamil Lelonek

32
งานนี้ แต่คำตอบไม่ได้ละห้อยงานไม่เพียงพอของการอธิบายว่าแต่ละโฟลเดอร์ย่อยที่คุณเพิ่มความต้องการที่จะมีสองภายในโฟลเดอร์ย่อยของมันซึ่งสามารถเรียกว่า "รูปแบบ" และทุกไฟล์รูปแบบของคุณต้องไปภายในของโฟลเดอร์ย่อยที่สอง การอ่านความคิดเห็นหลายสิบครั้งเพื่อให้ได้ผลนั้นอยู่ไกลจากอุดมคติ และสำหรับทุกคนที่กำลังมองหาการตั้งค่าโฟลเดอร์ย่อย "เลย์เอาต์" พิเศษเป็นวิธีแก้URI is not registeredปัญหา
59

233

คำตอบคือไม่

ฉันต้องการดึงดูดความสนใจของคุณที่มีต่อหนังสือเล่มนี้Pro Android 2ที่ระบุว่า:

นอกจากนี้ยังมีข้อ จำกัด เกี่ยวกับทรัพยากรอีกด้วย อันดับแรก Android รองรับเฉพาะรายการเชิงเส้นของไฟล์ภายในโฟลเดอร์ที่กำหนดไว้ล่วงหน้าภายใต้ res ตัวอย่างเช่น จะไม่สนับสนุนโฟลเดอร์ที่ซ้อนกันภายใต้โฟลเดอร์เค้าโครง (หรือโฟลเดอร์อื่น ๆ ภายใต้ความละเอียด)

ประการที่สองมีความคล้ายคลึงกันระหว่างโฟลเดอร์สินทรัพย์และโฟลเดอร์ raw ภายใต้ res ทั้งสองโฟลเดอร์สามารถมีไฟล์ raw ได้ แต่ไฟล์ภายใน raw ถือเป็นทรัพยากรและไฟล์ภายในสินทรัพย์ไม่ได้

โปรดทราบว่าเนื่องจากเนื้อหาของ สินทรัพย์โฟลเดอร์ไม่ถือว่าเป็นทรัพยากรที่คุณสามารถใส่ลำดับชั้นโดยพลการของไฟล์และโฟลเดอร์ภายใน มัน


3
ฉันขอแสดงความหวังที่ดีที่สุดต่อไปของเราคือปลั๊กอิน Eclipse หรือ IntelliJ ที่สามารถยุบไฟล์ตามคำนำหน้าชื่อไฟล์
Jerry Brady

15
@ จัสตินลองดูวิธีแก้ปัญหาที่ฉันโพสต์สำหรับการไล่ระดับสี
eski

ฉันคิดว่าวิธีแก้ปัญหาหนึ่งอาจตั้งชื่อไฟล์ตามที่คุณต้องการให้จัดหมวดหมู่ได้ดังนั้นจึงดูเหมือนว่าอยู่ในโฟลเดอร์ย่อย ฉันเพิ่ม "แท็กโฟลเดอร์ย่อย" ในส่วนต้นของชื่อ ตัวอย่างเช่น. กิจกรรมทั้งหมดจะเป็น "activity_activityname.xml" และกิจกรรมย่อยอาจเป็น "activity_activityname_childactivity.xml" และอื่น ๆ ไฟล์อื่น ๆ จะเป็น "other_filename.xml" นั่นคือสิ่งที่ฉันทำเพื่อหลีกเลี่ยงความสับสน ประณามใครบางคนเอาชนะฉันไป สามปี> <ฉันไม่ได้เห็น
Vedavyas Bhat

1
สิ่งสำคัญคือให้สังเกตที่นี่โดยการพิจารณาrawว่าเป็นทรัพยากรที่คุณจะได้รับความหนาแน่น / การวางแนว / เวอร์ชัน / ฯลฯ ขึ้นอยู่กับassetsว่าคุณต้องทำสิ่งใดด้วยตนเอง
TWiStErRob

1
เลือกคำตอบนี้เป็นข้อโต้แย้งในการหากระแสหลักของ Android
Zon

77

ฉันแค่ต้องการเพิ่มคำตอบที่ยอดเยี่ยมของ eskis สำหรับผู้ที่มีปัญหา (หมายเหตุ: นี่จะใช้งานได้และมีลักษณะเหมือนไดเรกทอรีแยกกันในมุมมอง 'โครงการ' ไม่ใช่มุมมอง 'android' อย่างน่าเสียดาย)

ทดสอบกับสิ่งต่อไปนี้ BuildToolsVersion = 23.0.0 gradle 1.2.3 และ 1.3.0

นี่คือวิธีที่ฉันได้รับของฉันเพื่อทำงานกับโครงการที่สร้างขึ้นแล้ว

  1. คัดลอกไฟล์ XML ทั้งหมดออกจากไดเรกทอรีเลย์เอาต์ของคุณและวางลงในไดเรกทอรีบนเดสก์ท็อปหรือบางอย่างเพื่อสำรอง
  2. ลบไดเรกทอรีเค้าโครงทั้งหมด (ตรวจสอบให้แน่ใจว่าคุณได้สำรองข้อมูลทุกอย่างตั้งแต่ขั้นตอนที่ 1 !!!)
  3. คลิกขวาที่ไดเร็กทอรี res และเลือก new> directory
  4. ตั้งชื่อไดเรกทอรีใหม่นี้ว่า "เลย์เอาต์" (สิ่งนี้อาจเป็นสิ่งที่คุณต้องการ แต่จะไม่ใช่ไดเรกทอรี 'แฟรกเมนต์' หรือไดเรกทอรี 'กิจกรรม' ซึ่งจะมาภายหลัง)
  5. คลิกขวาที่ไดเรกทอรี "เลย์เอาต์ใหม่" และเลือกไดเรกทอรี> ใหม่ (นี่จะเป็นชื่อประเภทของไฟล์ XML ที่คุณจะมีในตัวอย่างเช่น 'แฟรกเมนต์' และ 'กิจกรรม')
  6. คลิกขวาที่ไดเรกทอรี 'แฟรกเมนต์' หรือ 'กิจกรรม' (หมายเหตุ: นี่ไม่จำเป็นต้องเป็น 'แฟรกเมนต์' หรือ 'กิจกรรม' นั่นคือสิ่งที่ฉันใช้เป็นตัวอย่าง) และเลือกไดเรกทอรีใหม่อีกครั้งและตั้งชื่อไดเรกทอรีนี้อีกครั้ง "รูปแบบ" (หมายเหตุ: ต้องมีชื่อว่า 'เลย์เอาต์' !!! สำคัญมาก)
  7. ใส่ไฟล์ XML ที่คุณต้องการในไดเรกทอรี 'เลย์เอาต์' ใหม่จากข้อมูลสำรองที่คุณทำบนเดสก์ท็อป
  8. ทำซ้ำขั้นตอนที่ 5 - 7 สำหรับไดเรกทอรีที่กำหนดเองตามที่คุณต้องการ
  9. เมื่อเสร็จแล้วให้ไปที่ไฟล์โมดูล gradle.build ของคุณและสร้างคำนิยาม sourceSets เช่นนี้ ... (ตรวจสอบให้แน่ใจว่า 'src / main / res / layouts' & 'src / main / res' อยู่ด้านล่างเสมอสอง !! เหมือนที่ฉันแสดงด้านล่าง)

    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. กำไร $$$$

แต่อย่างจริงจัง .. นี่คือวิธีที่ฉันได้มันไปทำงาน แจ้งให้เราทราบหากใครมีคำถามใด ๆ .. ฉันสามารถลองช่วยได้

รูปภาพมีค่ามากกว่าคำพูด

โครงสร้างสารบบ


1
สิ่งที่เกี่ยวกับไดเรกทอรีรูปแบบเช่นlayout-v21?
Akshay Chordiya

4
ฉันไม่ได้ทดสอบ แต่ฉันจะจินตนาการว่าคุณเพิ่งสร้างโฟลเดอร์ layout-v21 ข้างโฟลเดอร์เค้าโครง
hitch.united

ทำงานบน gradle 2.0.0 และ buildToolsVersion 23.0.2! โปรดทราบว่าค่าการกำหนดค่าคือ'src/main/res/layouts/content'และเส้นทางของการกำหนดค่านี้คือ'src/main/res/layouts/content/layout'
cwhsu

3
ฉันมีปัญหากับstackoverflow.com/questions/41934004/
Petra Barus

2
ค้นหาชั่วขณะที่ไม่มีโชคนี่เป็นทางออกเดียวที่เหมาะกับฉัน ขอบคุณที่โพสต์คำตอบอย่างละเอียดพร้อมรูปภาพ!
Machine เผ่า

53

เป็นไปไม่ได้ แต่โฟลเดอร์เค้าโครงจะเรียงตามชื่อ ดังนั้นฉันจึงเติมชื่อไฟล์เลย์เอาต์ด้วยชื่อแพ็คเกจของฉัน เช่นสำหรับสองแพ็คเกจ "ซื้อ" และ "กำลังเล่น":

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

20

ฉันใช้ปลั๊กอินการจัดกลุ่มไฟล์ Androidสำหรับ Android Studio มันไม่ได้ช่วยให้คุณสร้างโฟลเดอร์ย่อย แต่สามารถแสดงไฟล์และทรัพยากรของคุณตามที่อยู่ในโฟลเดอร์ต่าง ๆ และนี่คือสิ่งที่ฉันต้องการ

คุณสามารถติดตั้งปลั๊กอิน "Android File Grouping" ได้

ของ windows:

Android Studio -> ไฟล์ -> การตั้งค่า -> ปลั๊กอิน

Mac:

Android Studio -> แท็บ Android Studio (บนซ้าย) -> การตั้งค่า -> ปลั๊กอิน -> ติดตั้งปลั๊กอิน JetBrains ..

สำหรับ Mac ฉันสามารถทดสอบได้และไม่สามารถค้นหาปลั๊กอินได้ ดังนั้นฉันจึงดาวน์โหลดปลั๊กอินจากที่นี่และใช้Install plugin from diskตัวเลือกจากการตั้งค่าด้านบน


แชร์ลิงก์ของปลั๊กอินนั้นด้วย!
Paresh Mayani

เสร็จสิ้น อย่างไรก็ตามคุณสามารถค้นหา "การจัดกลุ่มไฟล์ Android" ใน Android Studio -> ไฟล์ -> การตั้งค่า -> ปลั๊กอิน
ชาร์ป

3
ปลั๊กอินไม่ทำงานในมุมมอง "Android" เฉพาะมุมมอง "Project" เท่านั้น: /
Hugo Gresse

18

ขณะนี้มี Android Studio และ Gradle คุณสามารถมีโฟลเดอร์ทรัพยากรหลายโฟลเดอร์ในโครงการของคุณ อนุญาตให้จัดระเบียบไม่เพียง แต่ไฟล์เลย์เอาต์ของคุณ แต่ยังมีทรัพยากรประเภทใด ๆ

ไม่ใช่โฟลเดอร์ย่อย แต่อาจแยกส่วนของแอปพลิเคชันของคุณ

การกำหนดค่าเป็นดังนี้:

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

ตรวจสอบเอกสาร


2
ฉันสังเกตเห็นว่าทุกครั้งที่ฉันทำการเปลี่ยนแปลงเค้าโครงภายใต้การตั้งค่านี้ฉันต้องทำเสมอcleanเพื่อดูมันสะท้อนให้เห็นในแอป
Pawan Kumar

16

ฉันคิดว่าทางออกที่ดีที่สุดสำหรับปัญหานี้ (เนื่องจากไม่อนุญาตให้ใช้โฟลเดอร์ย่อย) คือการเติมชื่อไฟล์ด้วยชื่อของโฟลเดอร์ที่คุณจะวางไว้ข้างใน ตัวอย่างเช่นหากคุณมีเลย์เอาต์มากมายสำหรับกิจกรรมชิ้นส่วนหรือเพียงแค่มุมมองทั่วไปที่เรียกว่า "สถานที่" จากนั้นคุณควรจะเติมมันด้วย places_my_layout_name อย่างน้อยก็แก้ปัญหาการจัดระเบียบพวกเขาในแบบที่พวกเขาหาได้ง่ายกว่าใน IDE มันไม่ใช่ทางออกที่ยอดเยี่ยม แต่ก็ดีกว่าไม่มีอะไรเลย


16

ปัญหาเล็ก ๆ

ฉันสามารถบรรลุโฟลเดอร์ย่อยได้โดยทำตามคำตอบสูงสุดของคำถามนี้

อย่างไรก็ตามเมื่อโครงการขยายใหญ่ขึ้นคุณจะมีโฟลเดอร์ย่อยมากมาย:

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เป็นอาร์กิวเมนต์ The 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
}

หวังว่ามันจะช่วย!


ฉันใช้แนวทางของคุณ แต่จะใช้ในกิจกรรมได้อย่างไร ฉันสร้างโฟลเดอร์ย่อยในโฟลเดอร์เลย์เอาต์ชื่อ admin และมีรูปแบบ admin_home เมื่อฉันอยู่ในกิจกรรมและใช้setContentView(R.layout.Admin.admin_home .)Admin.admin_home ไม่ได้รับการแก้ไข
Asmaa Rashad

R.layout.admin_homeคุณควรจะสามารถใช้งานได้ตามปกติเช่น สคริปต์ควรเลือกชื่อให้คุณโดยอัตโนมัติ แจ้งให้เราทราบหากคุณสามารถทำงานได้
ฉันเป็นกบมังกร

มันใช้งานได้ดี แต่หลังจากเปลี่ยนบรรทัดนี้array.push("src/main/res");เป็นdef res="src/main/res"; array.push(res);เพราะฉันมีข้อผิดพลาดเนื่องจากการกดต้องการพารามิเตอร์ Gstring ไม่ใช่สตริงหนึ่ง. ถ้ามีคนใดมากกว่าที่ฉันพบข้อผิดพลาดนี้คุณสามารถแก้ไขได้
Asmaa Rashad

1
เลย์เอาต์ในโฟลเดอร์ย่อยไม่สามารถแก้ไข android namespace ได้ ความคิดใด ๆ
Jaguar

คุณสามารถยกเลิกการใส่// uncomment for debuggingเครื่องหมายบรรทัดเหล่านั้นด้วยและจากนั้นตรวจสอบว่าsrc/main/res/layouts/<your_layout_files>มีการตรวจพบผลลัพธ์อย่างถูกต้องหรือไม่?
ฉันเป็นกบมังกร

15

ตอนนี้เราสามารถทำได้อย่างง่ายดายด้วยปลั๊กอิน JetBrains ที่เรียกว่า " Android File Grouping "

ตรวจสอบลิงค์นี้

การจัดกลุ่มไฟล์ Android

ป้อนคำอธิบายรูปภาพที่นี่


จะต้องทำเครื่องหมายว่าเป็นคำตอบที่ถูกต้องเช่นเดียวกับการจัดระเบียบการจัดกลุ่มที่มีการประชุมชื่อง่าย ไม่จำเป็นต้องเปลี่ยน gradle หรือแม้แต่โครงสร้างไดเรคทอรีเริ่มต้นของแอพ เค้าโครงทั้งหมดยังคงอยู่ในโฟลเดอร์เค้าโครง แต่จัดกลุ่มไว้ในAndroid Studio
Alireza Fattahi

1
ไม่ควรเป็นคำตอบที่ได้รับการยอมรับเพราะมันไม่ได้ทำงานในมุมมอง Android .... (แต่ฉันชอบความคิด ^^)
Appyx

สิ่งนี้ไม่สามารถใช้งานได้กับ Android เวอร์ชั่นล่าสุดรุ่นล่าสุดหรือไม่
user3053247

7

วิธีที่ฉันทำคือการสร้างโฟลเดอร์ res แยกต่างหากในระดับเดียวกับโฟลเดอร์ res จริงในโครงการของคุณจากนั้นคุณสามารถใช้สิ่งนี้ในแอป build.gradle ของคุณ

android {
    //other stuff

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

โครงสร้างโฟลเดอร์ตัวอย่าง

จากนั้นแต่ละโฟลเดอร์ย่อยของโฟลเดอร์ res ใหม่ของคุณสามารถเป็นสิ่งที่เกี่ยวข้องกับแต่ละหน้าจอเฉพาะหรือบางสิ่งบางอย่างในแอปของคุณและแต่ละโฟลเดอร์จะมีlayout/ drawable/ valuesฯลฯของตัวเองทำให้สิ่งต่าง ๆ จัดระเบียบและคุณไม่ต้องอัปเดตไฟล์ คำตอบต้องการ (เพียงซิงค์การไล่ระดับสีของคุณทุกครั้งที่คุณเพิ่มโฟลเดอร์ทรัพยากรใหม่เพื่อให้รู้เกี่ยวกับมันและตรวจสอบให้แน่ใจว่าได้เพิ่มโฟลเดอร์ย่อยที่เกี่ยวข้องก่อนที่จะเพิ่มไฟล์ xml ของคุณ)


4

ตรวจสอบสคริปต์ Bash Flatten Folderที่แปลงลำดับชั้นโฟลเดอร์เป็นโฟลเดอร์เดียว


จะตรวจสอบออกเร็ว ๆ นี้ ขอบคุณ
Paresh Mayani

1
สคริปต์นั้นทำให้การเปลี่ยนชื่อไฟล์เพื่อรวมลำดับชั้นไดเรกทอรีในชื่อไฟล์ มันจะทำงานอย่างไรกับ Android IDE ของคุณกับชื่อไฟล์ที่เปลี่ยนแปลงไปทั่วสถานที่?
Stealth Rabbi

3

หากคุณกำลังพัฒนาบน linux หรือกล่อง mac วิธีแก้ปัญหาก็คือเพื่อสร้างโฟลเดอร์ย่อยซึ่งมีลิงก์สัญลักษณ์ไปยังเค้าโครงไฟล์ของคุณ เพียงใช้คำสั่ง ln ด้วย -s

ln -s PATH_TO_YOUR_FILE

ปัญหานี้คือว่าโฟลเดอร์เค้าโครงของคุณยังคงมีไฟล์. xml ทั้งหมด แต่คุณสามารถเลือกได้โดยใช้โฟลเดอร์ย่อย เป็นสิ่งที่ใกล้เคียงที่สุดกับสิ่งที่คุณต้องการ

ฉันเพิ่งอ่านว่าอาจทำงานกับ Windows ได้เช่นกันหากคุณใช้ Vista หรือใหม่กว่า มีmklinkคำสั่งนี้ แค่ google มันไม่เคยใช้มันด้วยตัวเอง

ปัญหาอื่นคือถ้าคุณเปิดไฟล์และลองเปิดอีกครั้งปลั๊กอินจะส่งข้อยกเว้นตัวชี้ NULL แต่มันไม่วางสาย


1
การวาง symlink ในการเอาชนะจุดประสงค์ในการทำให้การจัดเก็บเป็นโมดูลโดยแยกส่วนประกอบออกเป็นส่วนย่อยที่แตกต่างกัน: ทำให้มันซับซ้อนมากขึ้นแทนที่จะทำให้น้อยลง Gradle อนุญาตคุณสมบัติของไดเรกทอรีทรัพยากรเพิ่มเติม
RichieHH

3

ในขณะที่ข้อเสนอทั้งหมดสำหรับชุดทรัพยากรหลายชุดอาจใช้งานได้ปัญหาคือตรรกะปัจจุบันสำหรับปลั๊กอิน Android Studio Gradle จะไม่อัปเดตไฟล์ทรัพยากรหลังจากมีการเปลี่ยนแปลงสำหรับชุดทรัพยากรซ้อน การใช้งานปัจจุบันพยายามตรวจสอบไดเรกทอรีทรัพยากรโดยใช้ startsWith () ดังนั้นโครงสร้างไดเรกทอรีที่ซ้อนกัน (เช่น src / main / res / layout / layouts และ src / main / res / layout / layouts_category2) จะเลือก src / main / res / layout / layouts อย่างสม่ำเสมอและไม่เคยปรับปรุงการเปลี่ยนแปลง ผลลัพธ์ที่ได้คือคุณต้องสร้าง / ล้างโครงการในแต่ละครั้ง

ฉันส่งแพตช์มาที่https://android-review.googlesource.com/#/c/157971/เพื่อพยายามแก้ไขสิ่งต่าง ๆ


ฉันเห็นด้วยกับคุณว่า AS ไม่บันทึกการเปลี่ยนแปลงในไฟล์ XML แต่ทางออกคืออะไร? ผมจะพยายามstackoverflow.com/questions/32317822/...
CoolMind

3

คำตอบที่ดีที่สุดโดย @eski นั้นดี แต่รหัสไม่ได้สง่างามที่จะใช้ดังนั้นฉันจึงเขียนสคริปต์ groovy ในระดับเสียงสำหรับการใช้งานทั่วไป มันใช้กับชนิดบิลด์และรสชาติผลิตภัณฑ์ทั้งหมดและไม่เพียง แต่สามารถใช้สำหรับเลย์เอาต์คุณยังสามารถเพิ่มโฟลเดอร์ย่อยสำหรับประเภททรัพยากรอื่น ๆ เช่น drawable นี่คือรหัส (ใส่ไว้ใน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]
}

ในทางปฏิบัติต้องทำอย่างไร?

ตัวอย่างเช่นผมต้องการที่จะสร้างโฟลเดอร์ย่อยชื่อactivityสำหรับlayoutเพิ่มสตริงโดยใช้ชื่อใด ๆ ในresDirsตัวแปรเช่นlayoutsนั้นไฟล์ xml res\layouts\activity\layout\xxx.xmlรูปแบบที่ควรจะใส่ใน

ถ้าผมต้องการที่จะสร้างโฟลเดอร์ย่อยชื่อselectorsสำหรับdrawableเพิ่มสตริงโดยใช้ชื่อใด ๆ ในresDirsตัวแปรเช่นdrawablesนั้นไฟล์ xml drawable res\drawables\selectors\drawable\xxx.xmlควรจะใส่ใน

ชื่อโฟลเดอร์เช่นlayoutsและdrawablesถูกกำหนดในresDirsตัวแปรมันสามารถเป็นสตริงใด ๆ โฟลเดอร์ย่อยทั้งหมดที่คุณสร้างขึ้นเช่นactivityหรือselectorsถือเป็นresโฟลเดอร์เดียวกัน ดังนั้นในselectorsโฟลเดอร์เราต้องสร้างdrawableโฟลเดอร์เพิ่มเติมและวางไฟล์ xml ไว้ในdrawableโฟลเดอร์หลังจากที่ gradle นั้นสามารถรับรู้ไฟล์ xml ได้ตามปกติ


อันนี้ควรพิจารณาคำตอบที่ถูกต้อง! เรียบง่ายและทำงานได้อย่างสมบูรณ์แบบ!
Gláucio Leonardo Sant'ana

2

หากคุณใช้วิธีการในคำตอบที่ได้รับอนุมัติและต้องการปรับปรุงวิธีการเล็กน้อยให้เปลี่ยนการตั้งค่าการไล่ระดับสีดังนี้:

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

ดังนั้นหากคุณเพิ่มโฟลเดอร์และเลย์เอาต์มากขึ้นคุณไม่จำเป็นต้องกลับมาที่นี่อีกต่อไปแล้วผนวกรายการโฟลเดอร์ต้นทางที่มีขนาดยาวให้ gradle นำโฟลเดอร์ทั้งหมดมาให้คุณ


1
  • ขั้นตอนที่ 1: คลิกขวาที่เค้าโครง - แสดงใน explorer
  • ขั้นตอนที่ 2: เปิดโฟลเดอร์เค้าโครงและสร้างโฟลเดอร์ย่อยโดยตรง: layout_1, layout_2 ...
  • ขั้นตอนที่ 3: เปิด layout_1 สร้างเค้าโครงโฟลเดอร์ (หมายเหตุ: ชื่อบังคับคือเลย์เอาต์), เปิดโฟลเดอร์ layout_2 สร้างไดเรกทอรีย่อยเลย์เอาต์ (หมายเหตุ: ชื่อบังคับคือเลย์เอาต์) ...
  • ขั้นตอนที่ 4: คัดลอกไฟล์ xml ไปยังไดเรกทอรีย่อยเลย์เอาต์ใน layout_1 และ layout_2
  • ขั้นตอนที่ 5: เรียกใช้รหัสใน buid.grade (โมดูลแอป) และกดซิงค์ทันที:

sourceSets {
    main {
        res.srcDirs =
            [
                'src / main / res / layout / layout_1'
                'src / main / res / layout / layout_2',
                'src / main / res'
            ]
    }
}
  • ขั้นตอนที่ 6: สรุป: ขั้นตอนทั้งหมดข้างต้นจะช่วยให้จัดกลุ่มโฟลเดอร์และแสดงในโหมด 'โครงการ' เท่านั้นในขณะที่โหมด 'android' จะแสดงตามปกติ
  • ดังนั้นฉันจึงวาดว่าคำนำหน้าชื่ออาจจะมีประสิทธิภาพเท่ากับการทำคลัสเตอร์โฟลเดอร์

ขอบคุณสำหรับProjectโหมด ฉันไม่เข้าใจว่าโฟลเดอร์ย่อยหายไปไหน (ในAndroidโหมด)
CoolMind

0

คำตอบสั้น ๆ ก็คือไม่ แต่คุณสามารถมีหลายresโฟลเดอร์ได้อย่างแน่นอน ฉันคิดว่ามันใกล้เคียงกับที่คุณจะได้โฟลเดอร์ย่อยสำหรับlayoutโฟลเดอร์ นี่คือวิธีที่คุณทำ


1
ตรวจสอบคำตอบที่ยอมรับ ฉันไม่ได้ลองเป็นการส่วนตัว แต่ถ้าคุณสามารถตรวจสอบและอัปเดตแล้วมันจะเป็นประโยชน์!
Paresh Mayani

0

คำตอบยอดนิยมมีหลายข้อเสีย: คุณจะต้องเพิ่มเส้นทางรูปแบบใหม่เป็นสถานที่ทรัพยากรใหม่เพื่อโฟลเดอร์แทนres\layoutsres\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/ ในการสร้างโฟลเดอร์ย่อยคุณควรใช้เมนูนี้: ใหม่> โฟลเดอร์> โฟลเดอร์ใหม่

UPDATE

หลังจากสองสามสัปดาห์ที่ผ่านมาพบว่าการเปลี่ยนแปลงในทรัพยากรที่ไม่ได้สังเกตเห็นโดย Android สตูดิโอ ดังนั้นข้อผิดพลาดแปลก ๆ บางอย่างปรากฏขึ้น ตัวอย่างเช่นเลย์เอาต์ยังคงแสดงขนาดเดิมระยะขอบ บางครั้ง AS ไม่พบไฟล์ XML ใหม่ (โดยเฉพาะในช่วงเวลาทำงาน) บางครั้งมันผสมview ids (อ้างอิงถึงไฟล์ XML อื่น) มันมักจะต้องกดหรือBuild > Clean Project Build > Rebuild Projectอ่านRebuild ต้องหลังจากการเปลี่ยนแปลงรูปแบบไฟล์ XML ใน Android สตูดิโอ


ความคิดเห็นของคุณ 'ฉันสร้างโฟลเดอร์ด้วยบทความนี้ (ลิงก์ที่แนบมา)' ไม่ใช่วิธีที่ยอมรับได้ในการให้บริการโซลูชั่นที่นี่ดังนั้นคำตอบของคุณไม่ชัดเจน คุณอาจทิ้งคำแนะนำและให้เครดิตผู้แต่งด้วยลิงก์ มิฉะนั้นจะขี้เกียจ
jungledev

@jungledev เอาล่ะในที่สุดฉันก็ปฏิเสธความคิดนี้และกลับไปที่resโฟลเดอร์ดั้งเดิมเพราะ AS ไม่รองรับการแบ่งทรัพยากรออกเป็นโฟลเดอร์อย่างสมบูรณ์ อาจจะเปลี่ยนคำตอบหรือลบ แต่คุณหมายถึงอะไรเมื่อพูดว่ามันไม่ใช่วิธีที่ยอมรับได้ในการให้บริการโซลูชั่นบน SO?
CoolMind

ฉันหมายถึงสิ่งที่ฉันพูด อย่าพูดว่า 'ฉันทำกับบทช่วยสอนนี้ .... (ลิงก์แทรก)' สิ่งที่คุณควรพูดคือ: "ฉันทำตามบทช่วยสอนนี้ (แทรกลิงก์) และนี่คือขั้นตอนที่เหมาะกับฉันขั้นตอนที่ 1 ขั้นตอนที่ 2 ขั้นตอนที่ 3 ... ฯลฯ 'คุณต้องใส่ขั้นตอนที่นี่ในคำตอบด้วย การเชื่อมโยงไปยังบทช่วยสอนไม่สามารถยอมรับได้
jungledev

0

ไม่สามารถมีไดเรกทอรีย่อย (ง่าย) แต่คุณสามารถมีโฟลเดอร์ทรัพยากรเพิ่มเติม แปลกใจที่ไม่มีใครพูดถึงมันแล้ว แต่เพื่อเก็บโฟลเดอร์ทรัพยากรเริ่มต้นและเพิ่มอีก:

    sourceSets {
        main.res.srcDirs += ['src/main/java/XYZ/ABC']
    }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.