Je travaille sur une présentation de formulaire pour une connexion Activity
dans mon Android App. L'image ci-dessous est ce que je veux il ressemble à:
J'ai pu réaliser cette présentation avec le texte suivant XML. Le problème, c'est que c'est un peu hackish. J'ai dû coder en dur une largeur pour l'hôte EditText. Plus précisément, je devais préciser:
Android:layout_width="172dp"
J'aimerais vraiment donner un pourcentage de largeur à l'hôte et au port EditText. (Quelque chose comme 80% pour l'hôte, 20% pour le port.) Est-ce possible? Le code XML suivant fonctionne sur mon droïde, mais il ne semble pas fonctionner pour tous les écrans. J'aimerais vraiment une solution plus robuste.
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/main"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent" >
<TextView
Android:id="@+id/Host_label"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_below="@+id/home"
Android:paddingLeft="15dp"
Android:paddingTop="0dp"
Android:text="Host"
Android:textColor="#a5d4e2"
Android:textSize="25sp"
Android:textStyle="normal" />
<TextView
Android:id="@+id/port_label"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_below="@+id/home"
Android:layout_toRightOf="@+id/Host_input"
Android:paddingTop="0dp"
Android:text="port"
Android:textColor="#a5d4e2"
Android:textSize="25sp"
Android:textStyle="normal" />
<EditText
Android:id="@+id/Host_input"
Android:layout_width="172dp"
Android:layout_height="wrap_content"
Android:layout_below="@id/Host_label"
Android:layout_marginLeft="15dp"
Android:layout_marginRight="15dp"
Android:layout_marginTop="4dp"
Android:background="@Android:drawable/editbox_background"
Android:inputType="textEmailAddress" />
<EditText
Android:id="@+id/port_input"
Android:layout_width="100dp"
Android:layout_height="wrap_content"
Android:layout_below="@id/Host_label"
Android:layout_marginTop="4dp"
Android:layout_toRightOf="@id/Host_input"
Android:background="@Android:drawable/editbox_background"
Android:inputType="number" />
<TextView
Android:id="@+id/username_label"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_below="@+id/Host_input"
Android:paddingLeft="15dp"
Android:paddingTop="15dp"
Android:text="username"
Android:textColor="#a5d4e2"
Android:textSize="25sp"
Android:textStyle="normal" />
<EditText
Android:id="@+id/username_input"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:layout_below="@id/username_label"
Android:layout_marginLeft="15dp"
Android:layout_marginRight="15dp"
Android:layout_marginTop="4dp"
Android:background="@Android:drawable/editbox_background"
Android:inputType="textEmailAddress" />
<TextView
Android:id="@+id/password_label"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_below="@+id/username_input"
Android:paddingLeft="15dp"
Android:paddingTop="15dp"
Android:text="password"
Android:textColor="#a5d4e2"
Android:textSize="25sp"
Android:textStyle="normal" />
<EditText
Android:id="@+id/password_input"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:layout_below="@id/password_label"
Android:layout_marginLeft="15dp"
Android:layout_marginRight="15dp"
Android:layout_marginTop="4dp"
Android:background="@Android:drawable/editbox_background"
Android:inputType="textPassword" />
<ImageView
Android:id="@+id/home"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignParentTop="true"
Android:layout_centerHorizontal="true"
Android:layout_centerVertical="false"
Android:paddingLeft="15dp"
Android:paddingRight="15dp"
Android:paddingTop="15dp"
Android:scaleType="fitStart"
Android:src="@drawable/home" />
<Button
Android:id="@+id/login_button"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_below="@+id/password_input"
Android:layout_marginLeft="15dp"
Android:layout_marginTop="15dp"
Android:text=" login "
Android:textSize="18sp" >
</Button>
</RelativeLayout>
Vous recherchez l'attribut Android:layout_weight
. Cela vous permettra d'utiliser des pourcentages pour définir votre mise en page.
Dans l'exemple suivant, le bouton gauche utilise 70% de l'espace et le bouton droit 30%.
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="horizontal">
<Button
Android:text="left"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_weight=".70" />
<Button
Android:text="right"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_weight=".30" />
</LinearLayout>
Cela fonctionne de la même manière avec n'importe quel type de vue, vous pouvez remplacer les boutons par du texte de montage pour répondre à vos besoins.
Assurez-vous de régler le layout_width
sur 0dp
sinon vos vues risquent de ne pas être redimensionnées correctement.
Notez que la somme de poids ne doit pas nécessairement être égale à 1, je trouve juste que c'est plus facile à lire comme ça Vous pouvez définir le premier poids sur 7 et le second sur 3 pour obtenir le même résultat.
Cela ne répond pas tout à fait à la question initiale, qui concernait une scission 70/30, mais dans le cas particulier d'une scission 50/50 entre les composants, il existe un moyen: placez une entretoise invisible au centre et utilisez-la pour positionner le deux composantes d'intérêt.
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
<View Android:id="@+id/strut"
Android:layout_width="0dp"
Android:layout_height="0dp"
Android:layout_centerHorizontal="true"/>
<Button
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_alignRight="@id/strut"
Android:layout_alignParentLeft="true"
Android:text="Left"/>
<Button
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_alignLeft="@id/strut"
Android:layout_alignParentRight="true"
Android:text="Right"/>
</RelativeLayout>
Comme il s’agit d’un cas assez courant, cette solution est plus qu’une curiosité. C'est un peu un bidouillage, mais un efficace car la jambe de force de taille nulle devrait coûter très peu.
En général, cependant, il vaut mieux ne pas trop attendre du stock Android.
Comme indiqué par @EmJiHash PercentRelativeLayout est obsolète dans le niveau de l'API 26.0.0
Ci-dessous, citant le commentaire Google:
Cette classe était obsolète dans l'API de niveau 26.0.0. Pensez plutôt à utiliser ConstraintLayout et les mises en page associées. Ce qui suit montre comment répliquer la fonctionnalité des dispositions de pourcentage avec un objet ConstraintLayout.
Google a introduit une nouvelle API appelée Android.support.percent
Ensuite, vous pouvez simplement spécifier le pourcentage à prendre par vue
Ajouter une dépendance de compilation comme
compile 'com.Android.support:percent:22.2.0
en cela, PercentRelativeLayout est ce que nous pouvons faire en pourcentage
<Android.support.percent.PercentRelativeLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<ImageView
app:layout_widthPercent="50%"
app:layout_heightPercent="50%"
app:layout_marginTopPercent="25%"
app:layout_marginLeftPercent="25%"/>
</Android.support.percent.PercentRelativeLayout>
Vous ne pouvez pas utiliser les pourcentages pour définir les dimensions d'une vue dans une relation relative. La meilleure façon de le faire est d'utiliser LinearLayout et des poids, ou une disposition personnalisée.
Vous pouvez consulter la nouvelle bibliothèque de support en pourcentage.
compile 'com.Android.support:percent:22.2.0'
Vous pouvez utiliser PercentRelativeLayout . Il s’agit d’un ajout récent et non documenté à la bibliothèque de support de conception , qui permet de spécifier des éléments non seulement. les uns par rapport aux autres mais aussi le pourcentage total de l'espace disponible.
Sous-classe de RelativeLayout qui prend en charge les dimensions et les marges basées sur des pourcentages. Vous pouvez spécifier une dimension ou une marge d'enfant en utilisant des attributs avec le suffixe "Pourcent".
<Android.support.percent.PercentRelativeLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<ImageView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:layout_widthPercent="50%"
app:layout_heightPercent="50%"
app:layout_marginTopPercent="25%"
app:layout_marginLeftPercent="25%"/>
</Android.support.percent.PercentFrameLayout>
Le package Pourcentage fournit des API permettant de prendre en charge l'ajout et la gestion de dimensions basées sur un pourcentage dans votre application.
Pour l'utiliser, vous devez ajouter cette bibliothèque à votre liste de dépendances de Gradle:
dependencies {
compile 'com.Android.support:percent:22.2.0'//23.1.1
}
J'ai résolu ce problème en créant une vue personnalisée:
public class FractionalSizeView extends View {
public FractionalSizeView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FractionalSizeView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(width * 70 / 100, 0);
}
}
C'est une partie invisible que je peux utiliser pour aligner d'autres vues dans RelativeLayout.
Mise à jour
Comme indiqué par @EmJiHash, PercentRelativeLayout et PercentFrameLayout sont obsolètes dans le niveau 26.0.0 de l'API.
Pensez à utiliser ConstraintLayout
Google a introduit une nouvelle API appelée Android.support.percent
1) PercentRelativeLayout
2) PercentFrameLayout
Ajouter une dépendance de compilation comme
compile 'com.Android.support:percent:23.1.1'
Vous pouvez spécifier une dimension en pourcentage afin d’obtenir les avantages de RelativeLayout
et un pourcentage.
<Android.support.percent.PercentRelativeLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent"/>
<TextView
app:layout_widthPercent="40%"
app:layout_heightPercent="40%"
app:layout_marginTopPercent="15%"
app:layout_marginLeftPercent="15%"/>
</Android.support.percent.PercentRelativeLayout/>
Puisque PercentRelativeLayout était obsolète en 26.0.0 et que des dispositions imbriquées telles que LinearLayout dans RelativeLayout ont un impact négatif sur les performances ( Comprendre les avantages en termes de performances de ConstraintLayout ), la meilleure option pour atteindre un pourcentage de largeur consiste à remplacer votre RelativeLayout. avec ConstraintLayout.
Cela peut être résolu de deux manières.
SOLUTION N ° 1 Utilisation de recommandations avec un pourcentage de décalage
<Android.support.constraint.ConstraintLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<TextView
Android:id="@+id/Host_label"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="Host"
Android:layout_marginTop="16dp"
Android:layout_marginLeft="8dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="@+id/Host_input" />
<TextView
Android:id="@+id/port_label"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="Port"
Android:layout_marginTop="16dp"
Android:layout_marginLeft="8dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="@+id/port_input" />
<EditText
Android:id="@+id/Host_input"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_marginTop="8dp"
Android:layout_marginLeft="8dp"
Android:layout_marginRight="8dp"
Android:inputType="textEmailAddress"
app:layout_constraintTop_toBottomOf="@+id/Host_label"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/guideline" />
<EditText
Android:id="@+id/port_input"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_marginTop="8dp"
Android:layout_marginLeft="8dp"
Android:layout_marginRight="8dp"
Android:inputType="number"
app:layout_constraintTop_toBottomOf="@+id/port_label"
app:layout_constraintLeft_toLeftOf="@+id/guideline"
app:layout_constraintRight_toRightOf="parent" />
<Android.support.constraint.Guideline
Android:id="@+id/guideline"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:orientation="vertical"
app:layout_constraintGuide_percent="0.8" />
</Android.support.constraint.ConstraintLayout>
SOLUTION N ° 2 Utilisation d'une chaîne avec une largeur pondérée pour EditText
<Android.support.constraint.ConstraintLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<TextView
Android:id="@+id/Host_label"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="Host"
Android:layout_marginTop="16dp"
Android:layout_marginLeft="8dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="@+id/Host_input" />
<TextView
Android:id="@+id/port_label"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="Port"
Android:layout_marginTop="16dp"
Android:layout_marginLeft="8dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="@+id/port_input" />
<EditText
Android:id="@+id/Host_input"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_marginTop="8dp"
Android:layout_marginLeft="8dp"
Android:layout_marginRight="8dp"
Android:inputType="textEmailAddress"
app:layout_constraintHorizontal_weight="0.8"
app:layout_constraintTop_toBottomOf="@+id/Host_label"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/port_input" />
<EditText
Android:id="@+id/port_input"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_marginTop="8dp"
Android:layout_marginLeft="8dp"
Android:layout_marginRight="8dp"
Android:inputType="number"
app:layout_constraintHorizontal_weight="0.2"
app:layout_constraintTop_toBottomOf="@+id/port_label"
app:layout_constraintLeft_toRightOf="@+id/Host_input"
app:layout_constraintRight_toRightOf="parent" />
</Android.support.constraint.ConstraintLayout>
Dans les deux cas, vous obtenez quelque chose comme ça
PercentRelativeLayout est obsolète de la révision 26.0.0 de la bibliothèque de support.
Google a introduit une nouvelle mise en page appelée ConstraintLayout .
Ajoutez la bibliothèque en tant que dépendance dans votre fichier build.gradle au niveau du module:
dependencies {
compile 'com.Android.support.constraint:constraint-layout:1.0.1'
}
ajoutez simplement un fichier de mise en page:
<?xml version="1.0" encoding="utf-8"?>
<Android.support.constraint.ConstraintLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
</Android.support.constraint.ConstraintLayout>
Contraintes
Les contraintes vous aident à garder les widgets alignés. Vous pouvez utiliser des ancres, telles que les poignées de contrainte illustrées ci-dessous, pour déterminer les règles d'alignement entre différents widgets.
Wrap Content
: La vue se développe autant que nécessaire pour s'adapter à son contenu.Match Constraints
: La vue s'agrandit pour répondre à la définition de ses contraintes après comptabilisation des marges. Toutefois, si la dimension donnée n'a qu'une contrainte, la vue s'agrandit pour s'adapter à son contenu. L'utilisation de ce mode sur la hauteur ou la largeur vous permet également de définir un rapport de taille.Fixed
: vous spécifiez une dimension spécifique dans la zone de texte ci-dessous ou en redimensionnant la vue dans l'éditeur.Spread
: Les vues sont réparties uniformément (après la comptabilisation des marges). C'est la valeur par défaut.Spread inside
: La première et la dernière vue sont apposées sur les contraintes à chaque extrémité de la chaîne et le reste est uniformément réparti.Weighted
: Lorsque la chaîne est définie pour être étendue ou étendue à l'intérieur, vous pouvez remplir l'espace restant en définissant une ou plusieurs vues pour "faire correspondre les contraintes" (0dp). Par défaut, l'espace est uniformément réparti entre chaque vue définie pour "faire correspondre les contraintes", mais vous pouvez attribuer un poids d'importance à chaque vue à l'aide des attributs layout_constraintHorizontal_weight et layout_constraintVertical_weight. Si vous connaissez layout_weight dans une présentation linéaire, cela fonctionne de la même manière. Ainsi, la vue avec la valeur de poids la plus élevée reçoit le plus d’espace; les vues qui ont le même poids obtiennent le même espace.Packed
: les vues sont regroupées (après la prise en compte des marges). Vous pouvez ensuite ajuster le biais de la chaîne entière (gauche/droite ou haut/bas) en modifiant le biais de la vue de la tête de la chaîne.Center Horizontally or Center Vertically
: pour créer rapidement une chaîne de vues, sélectionnez-les toutes, cliquez avec le bouton droit de la souris sur l'une des vues, puis sélectionnez Centrer horizontalement ou Centrer verticalement pour créer une chaîne horizontale ou verticale.Baseline alignment
: Aligne la ligne de base du texte d'une vue sur la ligne de base du texte d'une autre vue.Constrain to a guideline
: Vous pouvez ajouter un repère vertical ou horizontal auquel vous pouvez contraindre des vues. Le repère sera invisible pour les utilisateurs de l'application. Vous pouvez positionner le repère dans la présentation en fonction des unités dp ou du pourcentage, par rapport au bord de la présentation.Adjust the constraint bias
: Lorsque vous ajoutez une contrainte aux deux côtés d'une vue (et que la taille de la vue pour la même dimension est "fixe" ou "envelopper le contenu"), la vue devient centrée entre les deux contraintes avec un biais de 50% par défaut. Vous pouvez ajuster le biais en faisant glisser le curseur de biais dans la fenêtre Propriétés.Set size as a ratio
: Vous pouvez définir la taille de la vue sur un rapport tel que 16: 9 si au moins une des dimensions de la vue est définie sur "respecter les contraintes" (0dp).Vous pouvez en apprendre plus depuis le fonctionnaire doc .
Il est intéressant de noter que, en s’appuyant sur la réponse de @olefevre, on peut non seulement réaliser des dispositions 50/50 avec des "entretoises invisibles", mais toutes sortes de dispositions impliquant une puissance de deux.
Par exemple, voici une disposition qui coupe la largeur en quatre parties égales (en réalité trois, avec des poids de 1, 1, 2):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="wrap_content" >
<View
Android:id="@+id/strut"
Android:layout_width="1dp"
Android:layout_height="match_parent"
Android:layout_centerHorizontal="true"
Android:background="#000000" />
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_toLeftOf="@+id/strut" >
<View
Android:id="@+id/left_strut"
Android:layout_width="1dp"
Android:layout_height="match_parent"
Android:layout_toLeftOf="@+id/strut"
Android:layout_centerHorizontal="true"
Android:background="#000000" />
<Button
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_alignParentLeft="true"
Android:layout_alignRight="@+id/left_strut"
Android:text="Far Left" />
<Button
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_alignParentRight="true"
Android:layout_toRightOf="@+id/left_strut"
Android:text="Near Left" />
</RelativeLayout>
<Button
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_alignLeft="@id/strut"
Android:layout_alignParentRight="true"
Android:text="Right" />
</RelativeLayout>
Vous pouvez accomplir cela via des poids de mise en page. Un poids détermine la façon dont les parties non réclamées de l'écran sont divisées. Donnez à chaque EditText une largeur de layout_width de 0 et un poids proportionnel. C'est-à-dire, attribuez à l'une un poids de 2 et à l'autre un poids de 1 si vous voulez que le premier occupe deux fois plus de place.
Il suffit de placer vos deux vues de texte hôte et port dans un affichage linéaire indépendant et d'utiliser Android: layout_weight pour définir le pourcentage.
Vérifiez https://github.com/mmin18/FlexLayout lequel vous pouvez utiliser le pourcentage ou l'expression Java directement dans la mise en forme xml.
<EditText
app:layout_left="0%"
app:layout_right="60%"
app:layout_height="wrap_content"/>
<EditText
app:layout_left="prev.right+10dp"
app:layout_right="100%"
app:layout_height="wrap_content"/>