À l’heure actuelle, je stocke chaque fichier de présentation XML dans le dossier res/layout
. Il est donc simple et pratique de gérer de petits projets. Toutefois, lorsqu’il s’agit de projets volumineux et lourds, une hiérarchie doit être créée. sous-dossiers nécessaires dans le dossier de présentation.
par exemple.
layout
-- layout_personal
-- personal_detail.xml
-- personal_other.xml
--layout_address
-- address1.xml
-- address2.xml
De la même manière, nous aimerions avoir des sous-dossiers pour la grande application. Y a-t-il moyen de le faire dans le projet Android?
Je suis en mesure de créer des sous-dossiers layout-personal et layout_address dans le dossier de présentation, mais lorsque vient le temps d'accéder au fichier de présentation XML à l'aide de R.layout ._______, il n'existe à ce moment-là aucune fenêtre contextuelle de présentation XML dans le dossier. m e n u.
Vous POUVEZ faire cela avec Gradle. J'ai fait un projet de démonstration montrant comment.
L'astuce consiste à utiliser la capacité de gradle à fusionner plusieurs dossiers de ressources et à définir le dossier res ainsi que les sous-dossiers imbriqués dans le bloc sourceSets.
Le problème, c'est que vous ne pouvez pas déclarer un dossier de ressources de conteneur avant de déclarer les dossiers de ressources enfants de ce dossier.
Ci-dessous se trouve le bloc sourceSets du fichier build.gradle de la démo. Notez que les sous-dossiers sont déclarés en premier.
sourceSets {
main {
res.srcDirs =
[
'src/main/res/layouts/layouts_category2',
'src/main/res/layouts',
'src/main/res'
]
}
}
De plus, le parent direct de vos fichiers de ressources actuels (pngs, mises en page xml, etc.) doit toujours correspondre à spécification .
La réponse est non.
Je voudrais attirer votre attention sur ce livre Pro Android 2 qui dit:
Il convient également de noter quelques contraintes en matière de ressources. Tout d'abord, Android ne prend en charge qu'une liste linéaire de fichiers dans les dossiers prédéfinis sous res. Par exemple, il ne prend pas en charge les dossiers imbriqués sous le dossier de présentation (ou les autres dossiers sous res).
Deuxièmement, il existe des similitudes entre le dossier assets et le dossier raw sous res. Les deux dossiers peuvent contenir des fichiers bruts, mais les fichiers contenus dans les fichiers bruts sont considérés comme des ressources, contrairement aux fichiers des ressources.
Notez que, dans la mesure où le contenu du dossier actifs n'est pas considéré comme une ressource, vous pouvez placer une hiérarchie arbitraire de dossiers et fichiers dans il.
Je voulais juste ajouter une réponse fantastique à eskis pour les personnes en difficulté. (Remarque: cela ne fonctionnera que et ressemblera à des répertoires distincts dans la vue "projet", pas à la vue "Android", malheureusement.)
Testé avec ce qui suit. BuildToolsVersion = 23.0.0 Gradle 1.2.3 & 1.3.0
C’est ainsi que j’ai eu le mien de travailler avec un projet déjà construit.
Une fois que cela est terminé, allez dans le fichier de vos modules gradle.build et créez une définition sourceSets comme celle-ci ... (Assurez-vous que 'src/main/res/layouts' et 'src/main/res' sont toujours les deux derniers!! !! Comme je montre ci-dessous).
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'
]
}
}
Bénéfice $$$$
Mais sérieusement… c'est comme ça que je l'ai fait fonctionner. Faites-moi savoir si quelqu'un a des questions .. Je peux essayer de vous aider.
Les images valent plus que des mots.
Impossible, mais le dossier de présentation est trié par nom. Donc, je préfixe les noms de fichier de mise en page avec mes noms de paquet. Par exemple. pour les deux forfaits "achat" et "jeu":
buying_bought_tracks.xml
buying_buy_tracks.xml
playing_edit_playlist.xml
playing_play_playlist.xml
playing_show_playlists.xml
J'utilise Android File Grouping plug-in pour Android Studio.Il ne vous permet pas vraiment de créer des sous-dossiers, mais il peut afficher vos fichiers et ressources car ils sont dans des dossiers différents . Et c'est exactement ce que je voulais.
Vous pouvez installer le plugin "Android File Grouping" en
Les fenêtres:
Android Studio -> Fichier -> Paramètres -> Plugins.
Mac:
Android Studio -> AndroidOnglet Studio (en haut à gauche) -> Préférences -> Plug-ins -> Installer le plug-in JetBrains ..
Pour Mac, j'ai pu le tester et je n'ai pas pu rechercher le plugin. J'ai donc téléchargé le plugin depuis ici et utilisé l'option Install plugin from disk
du paramètre ci-dessus.
Maintenant, avec Android Studio et Gradle, vous pouvez avoir plusieurs dossiers de ressources dans votre projet. Permettant d'organiser non seulement vos fichiers de mise en page, mais tout type de ressources.
Ce n'est pas exactement un sous-dossier, mais peut séparer des parties de votre application.
La configuration est la suivante:
sourceSets {
main {
res.srcDirs = ['src/main/res', 'src/main/res2']
}
}
Vérifiez le documentation .
Je pense que la solution la plus élégante à ce problème (étant donné que les sous-dossiers ne sont pas autorisés) est de faire précéder les noms de fichiers du nom du dossier dans lequel vous l'auriez placé. Par exemple, si vous avez plusieurs mises en page pour une activité, un fragment ou simplement une vue générale appelée "lieux", vous devez simplement l'ajouter à la fin avec places_my_layout_name. Au moins, cela résout le problème de leur organisation de manière à ce qu’ils soient plus faciles à trouver dans l’EDI. Ce n'est pas la solution la plus géniale, mais c'est mieux que rien.
Je peux obtenir des sous-dossiers en suivant le réponse du haut à cette question.
Cependant, au fur et à mesure que le projet grossit, vous aurez plusieurs sous-dossiers:
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'
]
}
}
Pas un gros problème, mais:
app/build.gradle
chaque fois que vous ajoutez un nouveau dossier.J'ai donc écrit une méthode Groovy simple pour récupérer tous les dossiers imbriqués:
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
}
Collez cette méthode en dehors du bloc Android {...}
dans votre app/build.gradle
.
Pour une structure comme celle-ci:
<project root>
├── app <---------- TAKE NOTE
├── build
├── build.gradle
├── gradle
├── gradle.properties
├── gradlew
├── gradlew.bat
├── local.properties
└── settings.gradle
Utilisez-le comme ceci:
Android {
sourceSets {
main {
res.srcDirs = getLayoutList("app/src/main/res/layouts/")
}
}
}
Si vous avez une structure comme celle-ci:
<project root>
├── my_special_app_name <---------- TAKE NOTE
├── build
├── build.gradle
├── gradle
├── gradle.properties
├── gradlew
├── gradlew.bat
├── local.properties
└── settings.gradle
Vous allez l'utiliser comme ça:
Android {
sourceSets {
main {
res.srcDirs = getLayoutList("my_special_app_name/src/main/res/layouts/")
}
}
}
getLayoutList()
prend a relative path
comme argument. Le relative path
est relatif à la racine du projet. Ainsi, lorsque nous saisirons "app/src/main/res/layouts/"
, il renverra le nom de tous les sous-dossiers sous la forme d'un tableau, qui sera exactement le même que:
[
'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'
]
Voici le script avec des commentaires pour la compréhension:
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
}
J'espère que ça aide!
Maintenant, nous pouvons facilement faire avec le plugin JetBrains appelé " Android File Grouping "
consultez ce lien
Une façon dont je l'ai fait était de créer un dossier de res séparé au même niveau que le dossier de res réel dans votre projet, vous pouvez ensuite l'utiliser dans votre application build.gradle
Android {
//other stuff
sourceSets {
main.res.srcDirs = ['src/main/res', file('src/main/layouts').listFiles()]
}
}
alors chaque sous-dossier de votre nouveau dossier res peut être quelque chose concernant chaque écran particulier ou quelque chose dans votre application, et chaque dossier aura son propre layout
/drawable
/values
etc gardant les choses organisées et vous n'avez pas besoin de mettre à jour le fichier gradle manuellement, comme le demandent certaines de ces autres réponses (il suffit de synchroniser votre diplôme chaque fois que vous ajoutez un nouveau dossier de ressources pour qu'il le sache, et assurez-vous d'ajouter les sous-dossiers appropriés avant d'ajouter vos fichiers xml) .
Vérifiez script Bash Flatten Folder qui convertit la hiérarchie des dossiers en un seul dossier
Si vous développez sur un Linux ou un Mac, une solution de contournement consisterait à créer des sous-dossiers contenant des liens symboliques vers vos fichiers de mise en page. Utilisez simplement la commande ln avec -s
ln -s PATH_TO_YOUR_FILE
Le problème avec ceci est que votre dossier Layout contient toujours tous les fichiers .xml. Mais vous pouvez bien sûr les sélectionner en utilisant les sous-dossiers. C'est la chose la plus proche de ce que vous voudriez avoir.
Je viens de lire que cela pourrait fonctionner avec Windows également si vous utilisez Vista ou une version ultérieure. Il y a cette commande mklink
. Il suffit de google, je ne l'ai jamais utilisé moi-même.
Un autre problème est que, si le fichier est ouvert et que vous essayez de le rouvrir, le plug-in génère une exception de pointeur NULL. Mais ça ne raccroche pas.
La meilleure réponse de @ eski est bonne, mais le code n’est pas élégant à utiliser; j’ai donc écrit un script groovy en dégradé pour un usage général. Il s'applique à tous les types de construction et toutes les variantes de produit. En plus de pouvoir être utilisé pour la présentation, vous pouvez également ajouter un sous-dossier pour tout autre type de ressource tel que drawable. Voici le code (mettez-le dans le bloc Android
du fichier de niveaux au niveau du projet):
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]
}
Comment faire en pratique?
Par exemple, je veux créer un sous-dossier nommé activity
pour layout
, ajouter une chaîne portant un nom quelconque dans la variable resDirs
telle que layouts
, puis le fichier de présentation XML doit être placé dans res\layouts\activity\layout\xxx.xml
.
Si je veux créer un sous-dossier nommé selectors
pour drawable
, ajoutez une chaîne portant un nom quelconque dans la variable resDirs
telle que drawables
, le fichier xml dessinable doit être placé dans res\drawables\selectors\drawable\xxx.xml
.
Le nom du dossier tel que layouts
et drawables
est défini dans la variable resDirs
, il peut s'agir de n'importe quelle chaîne. Tous les sous-dossiers créés par vous, tels que activity
ou selectors
, sont considérés comme identiques au dossier res
. Donc, dans le dossier selectors
, nous devons créer le dossier drawable
en plus et placer les fichiers xml dans le dossier drawable
, après quoi le gradé pourra reconnaître les fichiers xml comme pouvant être dessinés normalement.
Bien que toutes les propositions pour plusieurs ensembles de ressources puissent fonctionner, le problème est que la logique actuelle du plug-in Android Studio Gradle ne mettra pas à jour les fichiers de ressources après leur modification pour les ensembles de ressources imbriqués. L'implémentation actuelle tente de vérifier les répertoires de ressources à l'aide de startsWith (). Par conséquent, une structure de répertoires imbriquée (par exemple, src/main/res/layout/layouts et src/main/res/layout/layouts_category2) choisira src/main/res./layout/layouts de manière cohérente et ne met jamais à jour les modifications. Le résultat final est que vous devez reconstruire/nettoyer le projet à chaque fois.
J'ai soumis un correctif à l'adresse https://Android-review.googlesource.com/#/c/157971/ pour essayer de résoudre le problème.
Si vous utilisez la méthode dans la réponse approuvée et que vous souhaitez l’améliorer un peu, modifiez le paramètre de dégradé comme suit:
sourceSets {
main {
res.srcDirs = [
file("src/main/res/layouts/").listFiles(),
"src/main/res/layouts",
"src/main/res"
]
}
}
Donc, si vous ajoutez plus de dossiers et de dispositions, vous n'avez pas besoin de revenir ici et d'ajouter une longue liste de dossiers sources, laissez gradle obtenir tous les dossiers pour vous.
sourceSets {
main {
res.srcDirs =
[
'src / main / res / layout / layout_1'
'src / main / res / layout / layout_2',
'src / main / res'
]
}
}
Les principales réponses ont plusieurs inconvénients: vous devez ajouter de nouveaux chemins de présentation, AS place de nouvelles ressources dans le dossier res\layouts
au lieu de res\values
.
En combinant plusieurs réponses, j'ai écrit de manière similaire:
sourceSets {
main {
res.srcDirs =
[
'src/main/res',
file("src/main/res/layouts/").listFiles(),
'src/main/res/layouts'
]
}
}
J'ai créé des dossiers avec cet article: http://alexzh.com/tutorials/how-to-store-layouts-in-different-folders-in-Android-project/ . Pour créer des sous-dossiers, vous devez utiliser ce menu: Nouveau> Dossier> Dossier Res.
UPDATE
Après quelques semaines, j’ai constaté que les changements de ressources ne sont pas remarqués par Android Studio . Donc, des bugs étranges apparaissent. Par exemple, les mises en page continuent d'afficher les anciennes tailles et marges. Parfois, AS ne trouve pas de nouveaux fichiers XML (en particulier lors de l'exécution). Parfois, il mélange view id
s (références à un autre fichier XML). Il est souvent nécessaire d'appuyer sur Build > Clean Project
ou Build > Rebuild Project
. Lire Reconstruction requise après la modification des fichiers de présentation XML dans Android Studio .
Eh bien, la réponse courte est non. Mais vous pouvez certainement avoir plusieurs dossiers res
. Je pense que cela est aussi proche que possible des sous-dossiers du dossier layout
. Voici comment vous le faites.