web-dev-qa-db-ja.com

アプリケーションでAndroidによって選択されたレイアウトを検出するにはどうすればよいですか?

異なるリソースフォルダーに3つの異なるレイアウトを持つアクティビティがあるとします。例えば:

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

さまざまなデバイスとさまざまな位置で、それらの1つがAndroidによって選択されます。
どの1つが選択されているかをプログラムで見つけるにはどうすればよいですか

Androidは、これらのレイアウトをプログラムに返すAPIを持っていますか?


EditGraham Borlandのソリューション は、コメントで言及したいくつかの状況で問題があります。

68
Bobs

サポートされる構成ごとにvalues-<config>ディレクトリを作成できます。これらの各ディレクトリ内で、現在の構成を説明する単一のstrings.xml文字列でselected_configurationを作成します。実行時に、標準のgetStringメソッドを使用して文字列をフェッチします。これにより、構成の解決が行われ、構成の正しい文字列が返されます。これはテストされていません。

42
Edward Dale

異なるリソースファイルのビューに異なる _Android:tag_ 属性を設定し、 View.getTag() を使用して実行時にタグを読み戻すことができます。

例:

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") {
    ...
}
_
71
Graham Borland

このアルゴリズムを繰り返すことを試みることができます "How Android Finds the Best-matching Resource" -それは非常に簡単です、特に異なる画面にのみ異なるレイアウトがある場合。

8
Jin35

私の答えは@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以降で機能します。

5
Dinesh

setContentView(int resID)を使用してアクティビティのコンテンツを設定していると仮定しています。


METHOD 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を使用して、使用されているリソース識別子を知ることができます。


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

この場合、階層内のすべてのビューに同じタグが付けられます。

3
Sherif elKhatib

私はそれを見つける正確な方法を知らない。しかし、別の方法で見つけることができます。

すべてのレイアウトに1つのテキストビューを追加します(非表示)。それに応じて、xlarge、land、xlarge-landなどの値を割り当てます。

プログラムで、textviewから値を取得します。どういうわけかこのように知ることができます。

2
Raghu Nagaraju

Resourcesオブジェクトから画面の向きとサイズに関する情報を取得できます。そこから、どのレイアウトが使用されているかを理解できます。

getResources().getConfiguration().orientation;-_Configuration.ORIENTATION_PORTRAIT_または_Configuration.ORIENTATION_LANDSCAPE_を返します。

int size = getResources().getConfiguration().screenLayout;-画面サイズのマスクを返します。 Small、Normal、Large、xLargeサイズに対してテストできます。例えば:

_if ((size & Configuration.SCREENLAYOUT_SIZE_XLARGE)==Configuration.SCREENLAYOUT_SIZE_XLARGE)
_
2
sshturma

あなたの質問はこれと同じです レイアウト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`
1
VenomVendor