68 votes

Comment puis-je détecter quelle disposition est sélectionnée par Android dans mon application ?

Supposons que j'ai une activité avec trois mises en page différentes dans des dossiers de ressources différents. Par exemple :

layout-land/my_act.xml
layout-xlarge/my_act.xml
layout-xlarge-land/my_act.xml

Dans différents appareils et différentes positions, l'un d'entre eux est sélectionné par Android.
Comment puis-je savoir lequel est sélectionné de manière programmée ?

Android dispose-t-il d'une API qui renvoie ces mises en page au programme ?


Editar : La solution de Graham Borland a un problème dans certaines situations que j'ai mentionnées dans les commentaires.

71voto

Graham Borland Points 27556

Vous pouvez définir une autre android:tag sur les vues dans chaque fichier de ressources différent, et relire la balise au moment de l'exécution avec View.getTag() .

Exemple :

layout-xlarge-land/my_act.xml

<View
    android:id="@+id/mainview"
    android:tag="xlarge-landscape"
/>

layout-xlarge/mon_acte.xml

<View
    android:id="@+id/mainview"
    android:tag="xlarge-portrait"
/>

MonActivité.java

String tag = view.getTag();
if (tag.equals("xlarge-landscape") {
    ...
}

42voto

scompt.com Points 11304

Vous pourriez créer un values-<config> pour chacune de vos configurations prises en charge. À l'intérieur de chacun de ces répertoires, créez un fichier strings.xml avec un seul selected_configuration qui décrit la configuration actuelle. Au moment de l'exécution, récupérez la chaîne à l'aide de la fonction standard getString qui se chargera de la résolution de la configuration pour vous et renverra la chaîne correcte pour la configuration. Cette méthode n'est pas testée.

8voto

Jin35 Points 6244

Vous pouvez essayer de répéter cet algorithme "Comment Android trouve la ressource la mieux adaptée" - c'est assez simple, surtout si vous avez des mises en page différentes uniquement pour des écrans différents.

5voto

Dinesh Points 3334

Ma réponse est implémentée à partir de @Graham Borland

 @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
        switch(metrics.densityDpi){
             case DisplayMetrics.DENSITY_LOW:

             if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)
             {
               Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
               String tag = view.getTag();
               if (tag.equals("small-landscape") {
                .....
              }
             } 
            else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) 
            {
            Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
             String tag = view.getTag();
               if (tag.equals("small-potrait") {
                .....
              }
            }
            break;

             case DisplayMetrics.DENSITY_MEDIUM:

             if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)
             {
               Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
               String tag = view.getTag();
               if (tag.equals("medium-landscape") {
                .....
              }
             } 
            else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) 
            {
            Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
             String tag = view.getTag();
               if (tag.equals("medium-potrait") {
                .....
              }
            }
             break;

             case DisplayMetrics.DENSITY_HIGH:

               if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)
             {
               Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
               String tag = view.getTag();
               if (tag.equals("large-landscape") {
                .....
              }
             } 
            else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) 
            {
            Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
             String tag = view.getTag();
               if (tag.equals("large-potrait") {
                .....
              }
            }
             break;
        }

Cela fonctionnera dans l'API lavel 4 ou supérieure.

3voto

Sherif elKhatib Points 23987

Je suppose que vous utilisez setContentView(int resID) pour définir le contenu de vos activités.


MÉTHODE 1 (C'est ma réponse)

Maintenant, dans toutes vos mises en page, assurez-vous que la vue racine a toujours la bonne balise :

exemple :

layout-xlarge/main.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:tag="xlarge-landscape"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

</LinearLayout>

layout-small/main.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:tag="small"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

</LinearLayout>

Maintenant, laissez vos activités prolonger cette activité :

package shush.android.screendetection;

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class SkeletonActivity extends Activity {

    protected String resourceType;

    @Override
    public void setContentView(int layoutResID) {
        LayoutInflater inflater = getLayoutInflater();
        View view = inflater.inflate(layoutResID, null);
        resourceType = (String)view.getTag();
        super.setContentView(view);
    }
}

Dans ce cas, vous pouvez utiliser l'option resourceType pour savoir quel est l'identifiant de ressource utilisé.


MÉTHODE 2 (C'était ma réponse, mais avant de la poster, j'ai pensé à une meilleure réponse).

Maintenant, dans toutes vos mises en page, assurez-vous que la vue racine a toujours la bonne balise :

exemple :

layout-xlarge/main.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:tag="xlarge-landscape"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

</LinearLayout>

layout-small/main.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:tag="small"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

</LinearLayout>

Maintenant, laissez vos activités prolonger cette activité :

package shush.android.screendetection;

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class SkeletonActivity extends Activity {

    @Override
    public void setContentView(int layoutResID) {
        LayoutInflater inflater = getLayoutInflater();
        View view = inflater.inflate(layoutResID, null);
        fix(view, view.getTag());
        super.setContentView(view);
    }

    private void fix(View child, Object tag) {
        if (child == null)
            return;

        if (child instanceof ViewGroup) {
            fix((ViewGroup) child, tag);
        }
        else if (child != null) {
            child.setTag(tag);
        }
    }

    private void fix(ViewGroup parent, Object tag) {
        for (int i = 0; i < parent.getChildCount(); i++) {
            View child = parent.getChildAt(i);
            if (child instanceof ViewGroup) {
                fix((ViewGroup) child, tag);
            } else {
                fix(child, tag);
            }
        }
    }
}

Dans ce cas, toutes vos vues dans votre hiérarchie auront la même balise.

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