如何检测 Android 在我的应用程序中选择了哪个布局?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11205020/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I detect which layout is selected by Android in my application?
提问by Bobs
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
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.
How can I find out which one is selected programmatically?
在不同的设备和不同的位置,Android 选择其中之一。
如何找出以编程方式选择了哪一个?
Does Android have any API that returns these layouts to the program?
Android 是否有任何 API 可以将这些布局返回给程序?
Edit: Graham Borland's solutionhas a problem in some situations that I mentioned in the comments.
编辑:Graham Borland 的解决方案在我在评论中提到的某些情况下存在问题。
采纳答案by Edward Dale
You could create a values-<config>
directory for each of your supported configurations. Inside of each of those directories, create a strings.xml
with a single selected_configuration
string which describes the current 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. This is untested.
您可以values-<config>
为每个支持的配置创建一个目录。在每个目录中,创建一个strings.xml
带有selected_configuration
描述当前配置的字符串的文件。在运行时,使用标准getString
方法获取字符串,它将为您进行配置解析并返回正确的配置字符串。这是未经测试的。
回答by 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-land/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
我的活动.java
String tag = view.getTag();
if (tag.equals("xlarge-landscape") {
...
}
回答by Jin35
You can try to repeat this algorithm "How Android Finds the Best-matching Resource"- it's quite simple, especially if you have different layouts only for different screens.
您可以尝试重复此算法“Android 如何找到最匹配的资源”——它非常简单,尤其是当您仅针对不同的屏幕使用不同的布局时。
回答by Dinesh
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 或更高版本。
回答by Sherif elKhatib
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)
方法一(这是我的答案)
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.
在这种情况下,层次结构中的所有视图都将具有相同的标签。
回答by Raghu Nagaraju
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.
在所有布局中添加一个文本视图。(隐藏可见性)。相应地分配 xlarge、land、xlarge-land 等值。
In program, get the value from textview. Somehow we can get to know like this.
在程序中,从 textview 获取值。不知何故,我们可以像这样了解。
回答by sshturma
You can get info about screen orientation and size from Resources
object. From there you can understand which layout is used.
您可以从Resources
对象获取有关屏幕方向和大小的信息。从那里您可以了解使用了哪种布局。
getResources().getConfiguration().orientation;
- returns either Configuration.ORIENTATION_PORTRAIT
or Configuration.ORIENTATION_LANDSCAPE
.
getResources().getConfiguration().orientation;
- 返回Configuration.ORIENTATION_PORTRAIT
或Configuration.ORIENTATION_LANDSCAPE
。
int size = getResources().getConfiguration().screenLayout;
- returns mask of screen size. You can test against Small, Normal, Large, xLarge sizes. For example:
int size = getResources().getConfiguration().screenLayout;
- 返回屏幕大小的掩码。您可以针对 Small、Normal、Large、xLarge 尺寸进行测试。例如:
if ((size & Configuration.SCREENLAYOUT_SIZE_XLARGE)==Configuration.SCREENLAYOUT_SIZE_XLARGE)
回答by VenomVendor
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
您的问题与此相同如何获取布局xml文件路径?
您可以在 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.
确保文本视图的所有 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`