简体   繁体   English

如何在我的应用程序中检测Android选择的布局?

[英]How can I detect which layout is selected by Android in my application?

Assume I have an activity with three different layouts in different resource folders. 假设我在不同的资源文件夹中有三种不同布局的活动。 For example: 例如:

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

In different devices and different positions one of them is selected by Android. 在不同的设备和不同的位置,其中一个由Android选择。
How can I find out which one is selected programmatically ? 如何找出以编程方式选择的?

Does Android have any API that returns these layouts to the program? Android是否有任何API将这些布局返回给程序?


Edit : Graham Borland's solution has a problem in some situations that I mentioned in the comments. 编辑Graham Borland的解决方案在我在评论中提到的某些情况下存在问题。

You can set a different android:tag attribute on the views in each different resource file, and read the tag back at runtime with View.getTag() . 您可以在每个不同资源文件的视图上设置不同的android:tag属性,并使用View.getTag()在运行时读取标记。

Example: 例:

layout-xlarge-land/my_act.xml 布局XLARGE土地/ my_act.xml

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

layout-xlarge/my_act.xml 布局XLARGE / my_act.xml

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

MyActivity.java MyActivity.java

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

You could create a values-<config> directory for each of your supported configurations. 您可以为每个支持的配置创建values-<config>目录。 Inside of each of those directories, create a strings.xml with a single selected_configuration string which describes the current configuration. 在每个目录中,创建一个strings.xml其中包含一个selected_configuration字符串,用于描述当前配置。 At runtime, fetch the string using the standard getString method, which will do the configuration resolution for you and return the correct string for the configuration. 在运行时,使用标准getString方法获取字符串,该方法将为您执行配置解析并返回正确的配置字符串。 This is untested. 这是未经测试的。

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

My answer is implemented from @Graham Borland 我的回答是从@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;
        }

This will work in API lavel 4 or higher. 这将适用于API lavel 4或更高版本。

I am assuming you are using setContentView(int resID) to set the content of your activities. 我假设您正在使用setContentView(int resID)来设置活动的内容。


METHOD 1 (This is my answer) 方法1 (这是我的答案)

Now in all your layouts make sure that the root view always has the right tag: 现在,在所有布局中,确保根视图始终具有正确的标记:

example: 例:

layout-xlarge/main.xml : 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 : 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>

Now let your activities extend this activity: 现在让您的活动扩展此活动:

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

In this case, you can use the resourceType to know what is the resource identifier used. 在这种情况下,您可以使用resourceType来了解所使用的资源标识符。


METHOD 2 (This was my answer but before posting I thought of the better one) 方法2 (这是我的答案,但在发布之前,我想到了更好的一个)

Now in all your layouts make sure that the root view always has the right tag: 现在,在所有布局中,确保根视图始终具有正确的标记:

example: 例:

layout-xlarge/main.xml : 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 : 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>

Now let your activities extend this activity: 现在让您的活动扩展此活动:

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

In this case all your views in your hierarchy will have the same tag. 在这种情况下,层次结构中的所有视图都将具有相同的标记。

I dont know the exact way to find it. 我不知道找到它的确切方法。 But we can find it in different way. 但我们可以用不同的方式找到它。

Add one textview in all the layouts.(visibility hidden). 在所有布局中添加一个textview。(隐藏可见性)。 Assign values like xlarge, land, xlarge-land accordingly. 相应地分配像xlarge,land,xlarge-land这样的值。

In program, get the value from textview. 在程序中,从textview获取值。 Somehow we can get to know like this. 不知何故,我们可以这样了解。

You can get info about screen orientation and size from Resources object. 您可以从Resources对象获取有关屏幕方向和大小的信息。 From there you can understand which layout is used. 从那里你可以了解使用哪种布局。

getResources().getConfiguration().orientation; - returns either Configuration.ORIENTATION_PORTRAIT or Configuration.ORIENTATION_LANDSCAPE . - 返回Configuration.ORIENTATION_PORTRAITConfiguration.ORIENTATION_LANDSCAPE

int size = getResources().getConfiguration().screenLayout; - returns mask of screen size. - 返回屏幕大小的掩码。 You can test against Small, Normal, Large, xLarge sizes. 您可以针对Small,Normal,Large,xLarge大小进行测试。 For example: 例如:

if ((size & Configuration.SCREENLAYOUT_SIZE_XLARGE)==Configuration.SCREENLAYOUT_SIZE_XLARGE)

Your question is as same as this How to get layout xml file path? 您的问题与此如何获取布局xml文件路径相同?
You can add a Hidden Text View with corresponding Folder names in the xml Get the String in the text view by 您可以在xml中添加带有相应文件夹名称的隐藏文本视图。在文本视图中获取字符串

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

Make sure that all the id's of the text view are same. 确保文本视图的所有ID都相同。

Example

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`

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我如何拍摄我的Android应用程序/布局的快照 - how can i Take snapshots of my Android application/Layout 如何检测用户首次下载哪个版本的Android应用? - How can I detect which version of my Android app my user first downloaded? 如何从我的 Android 应用程序中的 Java 代码在我的布局上添加 NumberPicker? - How can I add NumberPicker on my Layout from Java code in my Android application? 如何改善我的android布局 - How can I improve my android layout 如何优化我的android布局? - How can i optimize my android layout? 在android中,是否可以从Mozilla将选定的文本发送到我的应用程序? - In android, Can I get a selected text to my Application from Mozilla? 我如何检测我的 android 应用程序是否被销毁/暂停/停止而不会失败? - How can I detect If my android application is Destroyed/Paused/Stopped without fail? 如何布局我的Android应用程序? - How to layout my android application? 如何强制我的Android应用程序只运行RTL布局directon? - How can I force my android application run only with RTL layout directon? Android如何将应用程序的xml布局修复为类似于移动设备的尺寸 - Android how can i fix the xml layout of my application to become like the dimensions of the mobile
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM