IT Share you

내 애플리케이션에서 Android가 선택한 레이아웃을 어떻게 감지 할 수 있습니까?

shareyou 2020. 11. 7. 17:57
반응형

내 애플리케이션에서 Android가 선택한 레이아웃을 어떻게 감지 할 수 있습니까?


서로 다른 리소스 폴더에 세 가지 레이아웃이있는 활동이 있다고 가정합니다. 예를 들면 :

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

다른 장치와 다른 위치에서 Android가 그중 하나를 선택합니다.
어떤 것이 프로그래밍 방식 으로 선택되었는지 어떻게 알 수 있습니까?

Android에 이러한 레이아웃을 프로그램에 반환하는 API가 있습니까?


편집 : Graham Borland의 솔루션 은 내가 의견에서 언급 한 일부 상황에서 문제가 있습니다.


values-<config>지원되는 각 구성에 대한 디렉토리를 만들 수 있습니다 . 각 디렉토리 안에 현재 구성을 설명 strings.xml하는 단일 selected_configuration문자열로를 만듭니다 . 런타임에 표준 getString방법을 사용하여 문자열을 가져 오면 구성 확인을 수행하고 구성에 대한 올바른 문자열을 반환합니다. 이것은 테스트되지 않았습니다.


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"
/>

MyActivity.java

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

이 알고리즘 "Android가 가장 일치하는 리소스를 찾는 방법" 을 반복 해 볼 수 있습니다 . 특히 화면마다 다른 레이아웃이있는 경우 매우 간단합니다.


내 대답은 @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 이상에서 작동합니다.


나는 당신이 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);
            }
        }
    }
}

이 경우 계층 구조의 모든 뷰에 동일한 태그가 있습니다.


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). Assign values like xlarge, land, xlarge-land accordingly.

In program, get the value from textview. Somehow we can get to know like this.


You can get info about screen orientation and size from Resources object. From there you can understand which layout is used.

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

int size = getResources().getConfiguration().screenLayout; - returns mask of screen size. You can test against Small, Normal, Large, xLarge sizes. 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?
You can add a Hidden Text View with corresponding Folder names in the xml Get the String in the text view by

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.

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`

참고URL : https://stackoverflow.com/questions/11205020/how-can-i-detect-which-layout-is-selected-by-android-in-my-application

반응형