Supposons que j'ai une activité avec trois dispositions différentes dans différents dossiers de ressources. 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'eux est sélectionné par Android.
Comment puis-je savoir lequel est sélectionné par programme?
Android possède-t-il une API qui renvoie ces dispositions au programme?
Edit : la solution de Graham Borland a un problème dans certaines situations que j'ai mentionnées dans les commentaires.
Vous pouvez créer un values-<config>
répertoire pour chacune de vos configurations prises en charge. À l'intérieur de chacun de ces répertoires, créez un strings.xml
avec un seul selected_configuration
chaîne qui décrit la configuration actuelle. Au moment de l'exécution, récupérez la chaîne à l'aide de la méthode standard getString
, qui effectuera la résolution de configuration pour vous et renverra la chaîne appropriée pour la configuration. Ceci n'est pas testé.
Vous pouvez définir un attribut Android:tag
différent sur les vues de 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/my_act.xml
<View
Android:id="@+id/mainview"
Android:tag="xlarge-portrait"
/>
MyActivity.Java
String tag = view.getTag();
if (tag.equals("xlarge-landscape") {
...
}
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 dispositions différentes uniquement pour différents écrans.
Ma réponse est mise en œuvre à 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 au niveau 4 ou supérieur de l'API.
Je suppose que vous utilisez setContentView(int resID)
pour définir le contenu de vos activités.
MÉTHODE 1 (Voici ma réponse)
Maintenant, dans toutes vos présentations, 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 le resourceType
pour savoir quel est l'identifiant de ressource utilisé.
MÉTHODE 2 (C'était ma réponse mais avant de poster je pensais à la meilleure)
Maintenant, dans toutes vos présentations, 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.
Je ne sais pas exactement comment le trouver. Mais nous pouvons le trouver de manière différente.
Ajoutez une vue de texte dans toutes les mises en page (visibilité masquée). Attribuez des valeurs telles que xlarge, land, xlarge-land en conséquence.
Dans le programme, obtenez la valeur de textview. D'une certaine manière, nous pouvons apprendre comme ça.
Vous pouvez obtenir des informations sur l'orientation et la taille de l'écran à partir de l'objet Resources
. De là, vous pouvez comprendre quelle disposition est utilisée.
getResources().getConfiguration().orientation;
- renvoie soit Configuration.ORIENTATION_PORTRAIT
soit Configuration.ORIENTATION_LANDSCAPE
.
int size = getResources().getConfiguration().screenLayout;
- retourne le masque de la taille de l'écran. Vous pouvez tester des tailles petites, normales, grandes et x grandes. Par exemple:
if ((size & Configuration.SCREENLAYOUT_SIZE_XLARGE)==Configuration.SCREENLAYOUT_SIZE_XLARGE)
Votre question est la même que celle-ci Comment obtenir le chemin du fichier xml de mise en page?
Vous pouvez ajouter une vue de texte masqué avec les noms de dossier correspondants dans le xml Récupérer la chaîne dans la vue de texte en
TextView path = (TextView)findViewbyid(R.id.hiddentextview);
String s = path.gettext().tostring();
Assurez-vous que tous les identifiants de la vue texte sont identiques.
Exemple
if your xml is in `normal-mdpi` in hidden textview hard code `normal-mdpi`
if your xml is in `large-mdpi` in hidden textview hard code `large-mdpi`