71

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

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

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

Androidには、これらのレイアウトをプログラムに返すAPIがありますか?


編集Graham Borlandのソリューションには、コメントで述べたいくつかの状況で問題があります。

4

8 に答える 8

73

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

例:

layout-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") {
    ...
}
于 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

私の答えは@GrahamBorlandから実装されています

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

これは、APIlavel4以降で機能します。

于 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_PORTRAIT-またはを返しますConfiguration.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

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

すべてのレイアウトに1つのテキストビューを追加します(非表示)。それに応じて、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 に答える