如何让应用程序自动适应不同的屏幕宽度
How to allow an app to adapt to different screen widths automatically
我深入研究了 this article,但无法找到任何解决方案。
我的问题:
我的所有屏幕中都包含 header 布局。根据屏幕的宽度,我想显示三种不同的 header 布局之一。边注;我的应用只支持纵向模式。
我的布局是:
- [图片][按钮][文字][按钮][文字] --> 适用于大屏幕
- [图片][按钮][文本][按钮] --> 适用于中等屏幕
- [图片] [按钮] [按钮] --> 适用于小屏幕
并且它们应该由应用程序根据屏幕宽度自动选择。我想以编程方式解决这个问题,因为我几乎需要在每个 activity 中执行此操作,所以如果可以正确完成以便系统可以处理它,那就太好了。
我试过了(但没用):
- 将三种不同的布局放入名为 "layout"、"layout-sw320dp"、"layout-sw400dp"
的 3 个不同文件夹中
- 将三种不同的布局放入名为 "layout"、"layout-xxhdpi"、"layout-xxxhdpi"
的 3 个不同文件夹中
非常感谢您提前的回答!
编辑:
布局实际上看起来比此处描述的要复杂一些。实际布局如下:
<LinearLayout>
<RelativeLayout>
<ImageView />
<LinearLayout>
<LinearLayout>
<ImageView />
<TextView />
</LinearLayout>
<LinearLayout>
<ImageView />
<TextView />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
另外,第一个 ImageView 中的图像是从互联网加载的,在加载之前我不知道它的大小。
我认为您必须获得每个页眉的布局宽度并为每个页眉制作不同的布局 header.then 以编程方式检查屏幕尺寸,并且在扩充布局之前您必须将页眉设置为符合您的宽度。
使用此代码获取设备的宽度:
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int height = displayMetrics.heightPixels;
int width = displayMetrics.widthPixels;
然后
if(width==smallDevice){ //or whatever condition you want
setHeaderLayoutFor("smallDevice");
}
else if(width=="mediumDevice"){
setHeaderLayoutFor("mediumDevice");
}
else if(width=="largerDevice"){
setHeaderLayoutFor("largeDevice");
}
并将 setHeaderLayoutFor(String layoutType) 设置为 set/inflate 布局。
我为您创建了这个布局。您只需要创建一个 XML 文件并将项目放入此容器中。设置元素的重要性。如果没有足够的 space,则重要性较低的项目将被移除(GONE)。如果您需要补充或更改内容,请告诉我。在我的设备上它有效。
例子
<com.sup.dev.android.views.widgets.layouts.LayoutImportance
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/red_700"
android:text="text_1"
app:LayoutImportance_Layout_importance="5"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/blue_700"
app:LayoutImportance_Layout_importance="1"
android:text="teeeeeeeeext_2"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/green_700"
app:LayoutImportance_Layout_importance="2"
android:text="teeeeeeeeext_3_teeeeext"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/amber_700"
app:LayoutImportance_Layout_importance="3"
android:text="teeeeeeeeext_4_teeeeeeeeeeeeeeeeeeext"/>
</com.sup.dev.android.views.widgets.layouts.LayoutImportance>
LayoutImportance.java
public class LayoutImportance extends LinearLayout {
private int lock;
public LayoutImportance(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (lock == 0) for (int i = 0; i < getChildCount(); i++) getChildAt(i).setVisibility(VISIBLE);
int w = MeasureSpec.getSize(widthMeasureSpec);
super.onMeasure(MeasureSpec.makeMeasureSpec(w, MeasureSpec.UNSPECIFIED), heightMeasureSpec);
if (getMeasuredWidth() > w) {
ArrayList<View> children = new ArrayList<>();
for (int i = 0; i < getChildCount(); i++) if (getChildAt(i).getVisibility() == VISIBLE) children.add(getChildAt(i));
if(children.isEmpty())return;
Collections.sort(children, (o1, o2) -> ((LayoutParams) o1.getLayoutParams()).importance - ((LayoutParams) o2.getLayoutParams()).importance);
children.get(0).setVisibility(GONE);
lock++;
onMeasure(widthMeasureSpec, heightMeasureSpec);
lock--;
}
}
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof LayoutParams;
}
@Override
protected LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(getContext(), null);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
}
@Override
protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
return new LayoutParams(p.width, p.height);
}
public static class LayoutParams extends LinearLayout.LayoutParams {
public int importance;
public LayoutParams(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LayoutImportance_Layout);
importance = a.getInt(R.styleable.LayoutImportance_Layout_LayoutImportance_Layout_importance, 0);
a.recycle();
}
public LayoutParams(int w, int h) {
super(w, h);
}
}
}
attrs.xml
<declare-styleable name="LayoutImportance_Layout">
<attr name="LayoutImportance_Layout_importance" format="integer"/>
</declare-styleable>
您可以使用 "Scalable dp"(sdp)。此尺寸单位随屏幕尺寸缩放。
将 sdp 添加到您的项目(使用 Android Studio 和 Gradle):
将 实现 'com.intuit.sdp:sdp-android:1.0.5' 添加到您的 build.gradle 依赖项块。
dependencies {
implementation 'com.intuit.sdp:sdp-android:1.0.5'
}
设计您的 xml 如下所示:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:gravity="center">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/give_us_a_review_landmine_main_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:paddingBottom="@dimen/_27sdp"
android:paddingLeft="@dimen/_43sdp"
android:paddingRight="@dimen/_43sdp"
android:paddingTop="@dimen/_50sdp" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Intuit"
android:textColor="@android:color/black"
android:textSize="@dimen/_40sdp"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/_minus10sdp"
android:paddingBottom="@dimen/_15sdp"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:includeFontPadding="false"
android:text="♡"
android:textColor="#ED6C27"
android:textSize="@dimen/_70sdp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:includeFontPadding="false"
android:text="U"
android:textColor="@android:color/black"
android:textSize="@dimen/_70sdp" />
</LinearLayout>
<TextView
android:id="@+id/give_us_a_review_landmine_text_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingBottom="@dimen/_12sdp"
android:text="Rate us so we can grow and help more people get their finances in check"
android:textColor="@android:color/black"
android:textSize="@dimen/_16sdp" />
<TextView
android:id="@+id/give_us_a_review_landmine_text_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="★★★★★"
android:textColor="#747474"
android:textSize="@dimen/_22sdp"
android:textStyle="bold" />
<Button
android:id="@+id/give_us_a_review_landmine_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="@dimen/_25sdp"
android:padding="@dimen/_8sdp"
android:text="Rate"
android:textSize="@dimen/_15sdp"
android:visibility="visible"
android:textColor="@android:color/white"
android:gravity="center"
android:minWidth="120dp"
android:includeFontPadding="false"
android:background="#0ac775"
android:singleLine="true" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
查看 link 了解更多信息:https://github.com/intuit/sdp
我深入研究了 this article,但无法找到任何解决方案。
我的问题: 我的所有屏幕中都包含 header 布局。根据屏幕的宽度,我想显示三种不同的 header 布局之一。边注;我的应用只支持纵向模式。
我的布局是:
- [图片][按钮][文字][按钮][文字] --> 适用于大屏幕
- [图片][按钮][文本][按钮] --> 适用于中等屏幕
- [图片] [按钮] [按钮] --> 适用于小屏幕
并且它们应该由应用程序根据屏幕宽度自动选择。我想以编程方式解决这个问题,因为我几乎需要在每个 activity 中执行此操作,所以如果可以正确完成以便系统可以处理它,那就太好了。
我试过了(但没用):
- 将三种不同的布局放入名为 "layout"、"layout-sw320dp"、"layout-sw400dp" 的 3 个不同文件夹中
- 将三种不同的布局放入名为 "layout"、"layout-xxhdpi"、"layout-xxxhdpi" 的 3 个不同文件夹中
非常感谢您提前的回答!
编辑: 布局实际上看起来比此处描述的要复杂一些。实际布局如下:
<LinearLayout>
<RelativeLayout>
<ImageView />
<LinearLayout>
<LinearLayout>
<ImageView />
<TextView />
</LinearLayout>
<LinearLayout>
<ImageView />
<TextView />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
另外,第一个 ImageView 中的图像是从互联网加载的,在加载之前我不知道它的大小。
我认为您必须获得每个页眉的布局宽度并为每个页眉制作不同的布局 header.then 以编程方式检查屏幕尺寸,并且在扩充布局之前您必须将页眉设置为符合您的宽度。
使用此代码获取设备的宽度:
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int height = displayMetrics.heightPixels;
int width = displayMetrics.widthPixels;
然后
if(width==smallDevice){ //or whatever condition you want
setHeaderLayoutFor("smallDevice");
}
else if(width=="mediumDevice"){
setHeaderLayoutFor("mediumDevice");
}
else if(width=="largerDevice"){
setHeaderLayoutFor("largeDevice");
}
并将 setHeaderLayoutFor(String layoutType) 设置为 set/inflate 布局。
我为您创建了这个布局。您只需要创建一个 XML 文件并将项目放入此容器中。设置元素的重要性。如果没有足够的 space,则重要性较低的项目将被移除(GONE)。如果您需要补充或更改内容,请告诉我。在我的设备上它有效。
例子
<com.sup.dev.android.views.widgets.layouts.LayoutImportance
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/red_700"
android:text="text_1"
app:LayoutImportance_Layout_importance="5"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/blue_700"
app:LayoutImportance_Layout_importance="1"
android:text="teeeeeeeeext_2"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/green_700"
app:LayoutImportance_Layout_importance="2"
android:text="teeeeeeeeext_3_teeeeext"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/amber_700"
app:LayoutImportance_Layout_importance="3"
android:text="teeeeeeeeext_4_teeeeeeeeeeeeeeeeeeext"/>
</com.sup.dev.android.views.widgets.layouts.LayoutImportance>
LayoutImportance.java
public class LayoutImportance extends LinearLayout {
private int lock;
public LayoutImportance(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (lock == 0) for (int i = 0; i < getChildCount(); i++) getChildAt(i).setVisibility(VISIBLE);
int w = MeasureSpec.getSize(widthMeasureSpec);
super.onMeasure(MeasureSpec.makeMeasureSpec(w, MeasureSpec.UNSPECIFIED), heightMeasureSpec);
if (getMeasuredWidth() > w) {
ArrayList<View> children = new ArrayList<>();
for (int i = 0; i < getChildCount(); i++) if (getChildAt(i).getVisibility() == VISIBLE) children.add(getChildAt(i));
if(children.isEmpty())return;
Collections.sort(children, (o1, o2) -> ((LayoutParams) o1.getLayoutParams()).importance - ((LayoutParams) o2.getLayoutParams()).importance);
children.get(0).setVisibility(GONE);
lock++;
onMeasure(widthMeasureSpec, heightMeasureSpec);
lock--;
}
}
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof LayoutParams;
}
@Override
protected LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(getContext(), null);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
}
@Override
protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
return new LayoutParams(p.width, p.height);
}
public static class LayoutParams extends LinearLayout.LayoutParams {
public int importance;
public LayoutParams(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LayoutImportance_Layout);
importance = a.getInt(R.styleable.LayoutImportance_Layout_LayoutImportance_Layout_importance, 0);
a.recycle();
}
public LayoutParams(int w, int h) {
super(w, h);
}
}
}
attrs.xml
<declare-styleable name="LayoutImportance_Layout">
<attr name="LayoutImportance_Layout_importance" format="integer"/>
</declare-styleable>
您可以使用 "Scalable dp"(sdp)。此尺寸单位随屏幕尺寸缩放。
将 sdp 添加到您的项目(使用 Android Studio 和 Gradle):
将 实现 'com.intuit.sdp:sdp-android:1.0.5' 添加到您的 build.gradle 依赖项块。
dependencies {
implementation 'com.intuit.sdp:sdp-android:1.0.5'
}
设计您的 xml 如下所示:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:gravity="center">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/give_us_a_review_landmine_main_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:paddingBottom="@dimen/_27sdp"
android:paddingLeft="@dimen/_43sdp"
android:paddingRight="@dimen/_43sdp"
android:paddingTop="@dimen/_50sdp" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Intuit"
android:textColor="@android:color/black"
android:textSize="@dimen/_40sdp"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/_minus10sdp"
android:paddingBottom="@dimen/_15sdp"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:includeFontPadding="false"
android:text="♡"
android:textColor="#ED6C27"
android:textSize="@dimen/_70sdp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:includeFontPadding="false"
android:text="U"
android:textColor="@android:color/black"
android:textSize="@dimen/_70sdp" />
</LinearLayout>
<TextView
android:id="@+id/give_us_a_review_landmine_text_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingBottom="@dimen/_12sdp"
android:text="Rate us so we can grow and help more people get their finances in check"
android:textColor="@android:color/black"
android:textSize="@dimen/_16sdp" />
<TextView
android:id="@+id/give_us_a_review_landmine_text_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="★★★★★"
android:textColor="#747474"
android:textSize="@dimen/_22sdp"
android:textStyle="bold" />
<Button
android:id="@+id/give_us_a_review_landmine_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="@dimen/_25sdp"
android:padding="@dimen/_8sdp"
android:text="Rate"
android:textSize="@dimen/_15sdp"
android:visibility="visible"
android:textColor="@android:color/white"
android:gravity="center"
android:minWidth="120dp"
android:includeFontPadding="false"
android:background="#0ac775"
android:singleLine="true" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
查看 link 了解更多信息:https://github.com/intuit/sdp