71

假设我在不同的资源文件夹中有一个具有三种不同布局的活动。例如:

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

在不同的设备和不同的位置,其中之一是由 Android 选择的。
如何找出以编程方式选择了哪一个?

Android 是否有任何 API 可以将这些布局返回给程序?


编辑Graham Borland 的解决方案在我在评论中提到的某些情况下存在问题。

4

8 回答 8

73

您可以android:tag在每个不同资源文件中的视图上设置不同的属性,并在运行时使用View.getTag().

例子:

布局-xlarge-land/my_act.xml

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

布局-xlarge/my_act.xml

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

我的活动.java

String tag = view.getTag();
if (tag.equals("xlarge-landscape") {
    ...
}
于 2012-06-26T10:19:59.583 回答
45

values-<config>您可以为每个受支持的配置创建一个目录。在每个目录中,使用描述当前配置strings.xml的单个字符串创建一个。selected_configuration在运行时,使用标准getString方法获取字符串,这将为您进行配置解析并为配置返回正确的字符串。这是未经测试的。

于 2012-07-26T13:32:24.873 回答
8

您可以尝试重复此算法“Android 如何找到最佳匹配资源” - 这很简单,特别是如果您仅针对不同的屏幕使用不同的布局。

于 2012-07-03T17:04:56.353 回答
5

我的答案是从@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;
        }

这将在 API lavel 4 或更高版本中工作。

于 2012-06-26T10:34:49.473 回答
3

我假设您正在使用setContentView(int resID)来设置活动的内容。


方法1 (这是我的答案)

现在在您的所有布局中确保根视图始终具有正确的标签:

例子:

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>

现在让您的活动扩展此活动:

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

在这种情况下,您可以使用resourceType来了解所使用的资源标识符。


方法2 (这是我的答案,但在发布之前我想到了更好的答案)

现在在您的所有布局中确保根视图始终具有正确的标签:

例子:

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>

现在让您的活动扩展此活动:

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

在这种情况下,层次结构中的所有视图都将具有相同的标签。

于 2012-06-29T20:14:37.057 回答
3

您可以从Resources对象获取有关屏幕方向和大小的信息。从那里您可以了解使用了哪种布局。

getResources().getConfiguration().orientation;- 返回Configuration.ORIENTATION_PORTRAITConfiguration.ORIENTATION_LANDSCAPE

int size = getResources().getConfiguration().screenLayout;- 返回屏幕大小的掩码。您可以针对 Small、Normal、Large、xLarge 尺寸进行测试。例如:

if ((size & Configuration.SCREENLAYOUT_SIZE_XLARGE)==Configuration.SCREENLAYOUT_SIZE_XLARGE)
于 2013-11-24T13:52:43.760 回答
2

我不知道找到它的确切方法。但我们可以通过不同的方式找到它。

在所有布局中添加一个文本视图。(隐藏可见性)。相应地分配 xlarge、land、xlarge-land 等值。

在程序中,从 textview 中获取值。不知怎的,我们可以像这样了解。

于 2012-06-26T10:22:52.847 回答
1

您的问题与如何获取布局 xml 文件路径相同?
您可以在 xml 中添加一个具有相应文件夹名称的隐藏文本视图通过以下方式获取文本视图中的字符串

TextView path = (TextView)findViewbyid(R.id.hiddentextview); 
 String s =  path.gettext().tostring();

确保文本视图的所有 id 都相同。

例子

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`
于 2012-07-24T17:07:30.190 回答