490 votes

Pourcentage de largeur dans un RelativeLayout

Je travaille sur la mise en page d'un formulaire de connexion. Activity dans mon application Android. L'image ci-dessous est celle à laquelle je veux que cela ressemble :

enter image description here

J'ai pu réaliser cette mise en page avec les éléments suivants XML . Le problème, c'est que c'est un peu bricolé. J'ai dû coder en dur une largeur pour l'EditText hôte. Plus précisément, j'ai dû spécifier :

android:layout_width="172dp" 

J'aimerais vraiment donner un pourcentage de largeur aux EditText de l'hôte et du port. (Quelque chose comme 80% pour l'hôte, 20% pour le port.) Est-ce possible ? Le XML suivant fonctionne sur mon Droid, 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>

0 votes

J'ai pris le temps de clarifier les choses en répondant à cette question similaire : stackoverflow.com/questions/7846614/

1 votes

Pensez à utiliser Android:hint dans EditText au lieu de TextView. Gagner de l'espace

0 votes

QUICONQUE cherche une démo de la bibliothèque de support de pourcentage code2concept.blogspot.in/2015/08/

832voto

Dalmas Points 13600

Vous êtes à la recherche de la android:layout_weight attribut. Il vous permettra d'utiliser des pourcentages pour définir votre mise en page.

Dans l'exemple suivant, le bouton de gauche utilise 70% de l'espace, et le bouton de droite 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 d'édition pour répondre à vos besoins.

Veillez à définir le layout_width à 0dp ou vos vues peuvent ne pas être mises à l'échelle correctement.

Notez que la somme des poids ne doit pas nécessairement être égale à 1, je trouve simplement que c'est plus facile à lire comme ça. Vous pouvez définir le premier poids à 7 et le second à 3 et cela donnera le même résultat.

177 votes

Ceci est logique pour l'utilisation de LinearLayout, mais il voulait un RelativeLayout. Y a-t-il un moyen de le faire, car j'ai besoin d'utiliser RelativeLayout pour un élément de liste ?

33 votes

Oui, créez un LinearLayout imbriqué à l'intérieur de votre RelativeLayout, où vous voulez utiliser les pourcentages.

17 votes

La réponse donnée ci-dessus par LadaRaider ne fonctionne pour moi que lorsque je fixe la largeur à 0px. Android:layout_width="0px"

297voto

olefevre Points 1882

Cela ne répond pas tout à fait à la question initiale, qui portait sur une répartition 70/30, mais dans le cas particulier d'une répartition 50/50 entre les composants, il existe une solution : placer une entretoise invisible au centre et l'utiliser pour positionner les deux composants concernés.

<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 hack mais un hack efficace car la jambe de force vide, de taille nulle, devrait coûter très peu.

D'une manière générale, il est préférable de ne pas trop attendre des mises en page standard d'Android...

8 votes

J'aime vraiment cette idée ! J'aime beaucoup RelativeLayout, et c'est une raison de plus pour moi d'éviter d'utiliser un TableLayout. Merci ! :)

21 votes

Ce que je veux savoir, c'est pourquoi nous avons besoin d'une solution de contournement. Il s'agit d'une fonctionnalité de base et de longue date du HTML. Les développeurs d'Android auraient sûrement pu jeter un coup d'oeil à HTML pour avoir une idée de ce dont les gens auront besoin et qu'ils utiliseront !

2 votes

@JohnK tout à fait d'accord. html/css est beaucoup mieux et plus simple que le système de mise en page d'Android.

82voto

Romain Guy Points 57114

Vous ne pouvez pas utiliser de pourcentages pour définir les dimensions d'une vue dans un RelativeLayout. La meilleure façon de le faire est d'utiliser LinearLayout et les poids, ou un Layout personnalisé.

17 votes

Il est temps de mettre à jour votre réponse, vous êtes l'élu ici :)

15voto

Ivan Volosyuk Points 161

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);
  }
}

Il s'agit d'un strut invisible que je peux utiliser pour aligner d'autres vues dans RelativeLayout.

3voto

Cheryl Simon Points 25259

Vous pouvez y parvenir en utilisant des poids de mise en page. Un poids détermine la façon dont les parties non réclamées de l'écran sont réparties. Donnez à chaque EditText une layout_width de 0, et un poids proportionnel. Par exemple, donnez à l'un un poids de 2, et à l'autre un poids de 1 si vous voulez que le premier occupe deux fois plus d'espace.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X