異なるリソースフォルダーに3つの異なるレイアウトを持つアクティビティがあるとします。例えば:
layout-land/my_act.xml
layout-xlarge/my_act.xml
layout-xlarge-land/my_act.xml
さまざまなデバイスとさまざまな位置で、それらの1つがAndroidによって選択されます。
どの1つが選択されているかをプログラムで見つけるにはどうすればよいですか?
Androidは、これらのレイアウトをプログラムに返すAPIを持っていますか?
Edit: Graham Borlandのソリューション は、コメントで言及したいくつかの状況で問題があります。
サポートされる構成ごとにvalues-<config>
ディレクトリを作成できます。これらの各ディレクトリ内で、現在の構成を説明する単一のstrings.xml
文字列でselected_configuration
を作成します。実行時に、標準のgetString
メソッドを使用して文字列をフェッチします。これにより、構成の解決が行われ、構成の正しい文字列が返されます。これはテストされていません。
異なるリソースファイルのビューに異なる _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") {
...
}
_
このアルゴリズムを繰り返すことを試みることができます "How Android Finds the Best-matching Resource" -それは非常に簡単です、特に異なる画面にのみ異なるレイアウトがある場合。
私の答えは@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)
を使用してアクティビティのコンテンツを設定していると仮定しています。
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);
}
}
}
}
この場合、階層内のすべてのビューに同じタグが付けられます。
私はそれを見つける正確な方法を知らない。しかし、別の方法で見つけることができます。
すべてのレイアウトに1つのテキストビューを追加します(非表示)。それに応じて、xlarge、land、xlarge-landなどの値を割り当てます。
プログラムで、textviewから値を取得します。どういうわけかこのように知ることができます。
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)
_
あなたの質問はこれと同じです レイアウト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`