1、引言
设备尺寸适配的重要性想必就不用我多说了,在我发布的历史文章中我曾谈过Qt中的设备尺寸适配问题,那这里我就来教大家如何在android中做设备尺寸适配。在android中设备尺寸适配的方式有好几种,但我喜欢的还是使用获取设备真实尺寸然后按照百分比重新设置控件大小的方式,因此接下来我就只演示这一种方法。
2、准备工作
2.1、生成接口类
首先需要生成一个接口类,便于区分不同的操作,使用时需要让activity或者fragment继承该接口,具体代码如下:
package xyz.dritrtj.uisize;
public interface Init {
/**
* 初始化视图控件,并设置监听
*/
public abstract void initView();
/**
* 设置控件尺寸属性
*/
public abstract void setViewSize();
/**
* 设置数据
*/
public abstract void setData();
}
2.2、生成UI尺寸工具类
工具类代码如下,下面会对工具类使用进行讲解:
package xyz.dritrtj.uisize;
import android.graphics.Color;
import android.graphics.drawable.GradientDrawable;
import android.util.TypedValue;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
/**
* 用于适配UI控件尺寸
*/
public class SetUiSize {
public static float displayWidth;//屏幕宽度 单位像素
public static float displayHeight;//屏幕高度 单位像素
public static float statusHeight;//状态栏高度 单位像素,暂时没有获取
public static float displayWidthDp = 411;//屏幕默认宽度 单位dp
public static float displayHeightDp = 731;//屏幕默认高度 单位dp
/**
* 设置背景
* @param v
*/
public static void setBackground(View v){
GradientDrawable drawable= (GradientDrawable) v.getBackground();
int size= (int) (10/SetUiSize.displayWidthDp*SetUiSize.displayWidth);
//两个参数表示一个角,按照左上角,右上角,右下角,左下角的顺序用两个相同的数据表示
drawable.setCornerRadii(new float[]{size,size,size,size,size,size,size,size});
size= (int) (0.38f/SetUiSize.displayWidthDp*SetUiSize.displayWidth);
if (size==0){//避免因为数值转化变为零
size=1;
}
drawable.setStroke(size, Color.parseColor("#c5c5c5"));
}
/**
* 设置圆角
* @param v
* @param radius
*/
public static void setRadius(View v,int radius){
GradientDrawable drawable= (GradientDrawable) v.getBackground();
int size= (int) (radius/SetUiSize.displayWidthDp*SetUiSize.displayWidth);
//两个参数表示一个角,按照左上角,右上角,右下角,左下角的顺序用两个相同的数据表示
drawable.setCornerRadii(new float[]{size,size,size,size,size,size,size,size});
}
/**
* 设置背景
* @param v
* @param strokeColor
*/
public static void setBackground(View v,String strokeColor,String solidColor){
GradientDrawable drawable= (GradientDrawable) v.getBackground();
int size= (int) (5/SetUiSize.displayWidthDp*SetUiSize.displayWidth);
//两个参数表示一个角,按照左上角,右上角,右下角,左下角的顺序用两个相同的数据表示
drawable.setCornerRadii(new float[]{size,size,size,size,size,size,size,size});
size= (int) (1/SetUiSize.displayWidthDp*SetUiSize.displayWidth);
drawable.setStroke(size, Color.parseColor(strokeColor));
drawable.setColor(Color.parseColor(solidColor));
}
/**
* 设置背景
* @param v
* @param strokeColor
* @param solidColor
* @param width
*/
public static void setBackground(View v,String strokeColor,String solidColor,int width){
GradientDrawable drawable= (GradientDrawable) v.getBackground();
int size= (int) (5/SetUiSize.displayWidthDp*SetUiSize.displayWidth);
//两个参数表示一个角,按照左上角,右上角,右下角,左下角的顺序用两个相同的数据表示
drawable.setCornerRadii(new float[]{size,size,size,size,size,size,size,size});
size= (int) (width/SetUiSize.displayWidthDp*SetUiSize.displayWidth);
drawable.setStroke(size, Color.parseColor(strokeColor));
drawable.setColor(Color.parseColor(solidColor));
}
/**
* 设置圆形的选择按钮
* @param v
*/
public static void setCircle(View v){
GradientDrawable drawable= (GradientDrawable) v.getBackground();
int size= (int) (16/SetUiSize.displayWidthDp*SetUiSize.displayWidth);
drawable.setSize(size,size);
size= (int) (4/SetUiSize.displayWidthDp*SetUiSize.displayWidth);
drawable.setStroke(size, Color.parseColor("#dedede"));
}
/**
* 设置TextView字体尺寸
* @param tv
* @param originSize 原始尺寸
*/
public static void setTextViewSize(TextView tv, float originSize){
int size= (int) (originSize/displayWidthDp*displayWidth);
tv.setTextSize(TypedValue.COMPLEX_UNIT_PX,size);//px
// tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP,size);//dp
// tv.setTextSize(TypedValue.COMPLEX_UNIT_SP,size);//sp
}
/**
* 设置Button字体尺寸
* @param btn
* @param originSize 原始尺寸
*/
public static void setButtonSize(Button btn, float originSize){
int size= (int) (originSize/displayWidthDp*displayWidth);
btn.setTextSize(TypedValue.COMPLEX_UNIT_PX,size);//px
}
/**
* 设置EditText字体尺寸
* @param et
* @param originSize 原始尺寸
*/
public static void setEditTextSize(EditText et, float originSize){
int size= (int) (originSize/displayWidthDp*displayWidth);
et.setTextSize(TypedValue.COMPLEX_UNIT_PX,size);//px
}
/**
* 父控件为RelativeLayout时设置底部边距
* @param view
* @param originSize
*/
public static void setMarginBottomRelative(View view, float originSize){
int size= (int) (originSize/displayWidthDp*displayWidth);
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
layoutParams.bottomMargin=size;
view.setLayoutParams(layoutParams);
}
/**
* 父控件为LinearLayout时设置底部边距
* @param view
* @param originSize
*/
public static void setMarginBottomLinear(View view, float originSize){
int size= (int) (originSize/displayWidthDp*displayWidth);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) view.getLayoutParams();
layoutParams.bottomMargin=size;
view.setLayoutParams(layoutParams);
}
/**
* 父控件为RelativeLayout时设置顶部边距
* @param view
* @param originSize
*/
public static void setMarginTopRelative(View view, float originSize){
int size= (int) (originSize/displayWidthDp*displayWidth);
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
layoutParams.topMargin=size;
view.setLayoutParams(layoutParams);
}
/**
* 父控件为LinearLayout时设置顶部边距
* @param view
* @param originSize
*/
public static void setMarginTopLinear(View view, float originSize){
int size= (int) (originSize/displayWidthDp*displayWidth);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) view.getLayoutParams();
layoutParams.topMargin=size;
view.setLayoutParams(layoutParams);
}
/**
* 父控件为RelativeLayout时设置左边距
* @param view
* @param originSize
*/
public static void setMarginLeftRelative(View view, float originSize){
int size= (int) (originSize/displayWidthDp*displayWidth);
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
layoutParams.leftMargin=size;
view.setLayoutParams(layoutParams);
}
/**
* 父控件为LinearLayout时设置左边距
* @param view
* @param originSize
*/
public static void setMarginLeftLinear(View view, float originSize){
int size= (int) (originSize/displayWidthDp*displayWidth);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) view.getLayoutParams();
layoutParams.leftMargin=size;
view.setLayoutParams(layoutParams);
}
/**
* 父控件为RelativeLayout时设置右边距
* @param view
* @param originSize
*/
public static void setMarginRightRelative(View view, float originSize){
int size= (int) (originSize/displayWidthDp*displayWidth);
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
layoutParams.rightMargin=size;
view.setLayoutParams(layoutParams);
}
/**
* 父控件为LinearLayout时设置右边距
* @param view
* @param originSize
*/
public static void setMarginRightLinear(View view, float originSize){
int size= (int) (originSize/displayWidthDp*displayWidth);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) view.getLayoutParams();
layoutParams.rightMargin=size;
view.setLayoutParams(layoutParams);
}
/**
* 父控件为RelativeLayout时设置边距
* @param view
* @param originSize
*/
public static void setMarginRelative(View view, float originSize){
setMarginHorizontalRelative(view,originSize);
setMarginVerticalRelative(view,originSize);
}
/**
* 父控件为LinearLayout时设置边距
* @param view
* @param originSize
*/
public static void setMarginLinear(View view, float originSize){
setMarginHorizontalLinear(view,originSize);
setMarginVerticalLinear(view,originSize);
}
/**
* 父控件为RelativeLayout时设置layout_marginHorizontal边距
* @param view
* @param originSize
*/
public static void setMarginHorizontalRelative(View view, float originSize){
int size= (int) (originSize/displayWidthDp*displayWidth);
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
layoutParams.rightMargin=size;
layoutParams.leftMargin=size;
view.setLayoutParams(layoutParams);
}
/**
* 父控件为LinearLayout时设置layout_marginHorizontal边距
* @param view
* @param originSize
*/
public static void setMarginHorizontalLinear(View view, float originSize){
int size= (int) (originSize/displayWidthDp*displayWidth);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) view.getLayoutParams();
layoutParams.rightMargin=size;
layoutParams.leftMargin=size;
view.setLayoutParams(layoutParams);
}
/**
* 父控件为RelativeLayout时设置layout_marginVertical边距
* @param view
* @param originSize
*/
public static void setMarginVerticalRelative(View view, float originSize){
int size= (int) (originSize/displayWidthDp*displayWidth);
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
layoutParams.topMargin=size;
layoutParams.bottomMargin=size;
view.setLayoutParams(layoutParams);
}
/**
* 父控件为LinearLayout时设置layout_marginVertical边距
* @param view
* @param originSize
*/
public static void setMarginVerticalLinear(View view, float originSize){
int size= (int) (originSize/displayWidthDp*displayWidth);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) view.getLayoutParams();
layoutParams.topMargin=size;
layoutParams.bottomMargin=size;
view.setLayoutParams(layoutParams);
}
/**
* 父控件为RelativeLayout时设置高度
* @param view
* @param originSize
*/
public static void setHeightRelative(View view, float originSize){
int size= (int) (originSize/displayWidthDp*displayWidth);
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
layoutParams.height=size;
view.setLayoutParams(layoutParams);
}
/**
* 父控件为LinearLayout时设置高度
* @param view
* @param originSize
*/
public static void setHeightLinear(View view, float originSize){
int size= (int) (originSize/displayWidthDp*displayWidth);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) view.getLayoutParams();
layoutParams.height=size;
view.setLayoutParams(layoutParams);
}
/**
* 父控件为RelativeLayout时设置宽度
* @param view
* @param originSize
*/
public static void setWidthRelative(View view, float originSize){
int size= (int) (originSize/displayWidthDp*displayWidth);
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
layoutParams.width=size;
view.setLayoutParams(layoutParams);
}
/**
* 父控件为LinearLayout时设置宽度
* @param view
* @param originSize
*/
public static void setWidthLinear(View view, float originSize){
int size= (int) (originSize/displayWidthDp*displayWidth);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) view.getLayoutParams();
layoutParams.width=size;
view.setLayoutParams(layoutParams);
}
/**
* 设置GridView的verticalSpacing
*/
public static void setVerticalSpacing(GridView view, float originSize){
int size= (int) (originSize/displayWidthDp*displayWidth);
view.setVerticalSpacing(size);
}
/**
* 设置padding
*/
public static void setPadding(View view, int left, int top, int right, int bottom){
left= (int) (left/displayWidthDp*displayWidth);
top= (int) (top/displayWidthDp*displayWidth);
right= (int) (right/displayWidthDp*displayWidth);
bottom= (int) (bottom/displayWidthDp*displayWidth);
view.setPadding(left,top,right,bottom);
}
}
3、使用方法
3.1、初始化
首先需要实现接口类,进行相关初始化操作,这里以activity为例,这里最主要的是在setViewSize方法中获取当前设备尺寸,这个一定要放在第一个活动界面中进行初始化,避免后面重复初始化,获取的设备尺寸以像素为单位,代码如下:
package xyz.dritrtj.uisize;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Color;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Display;
import android.view.View;
public class UiSizeActivity extends AppCompatActivity implements Init{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ui_size);
initView();
setViewSize();
setData();
}
@Override
public void initView() {
//初始化状态栏
View decorView=getWindow().getDecorView();//获取当前界面的DecorView
int option=View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;//更改文字颜色为深黑色
decorView.setSystemUiVisibility(option);//设置系统UI元素的可见性
getWindow().setNavigationBarColor(Color.TRANSPARENT);
getWindow().setStatusBarColor(Color.parseColor("#ffffff"));//将状态栏背景设置为白色
getSupportActionBar().hide();
}
@Override
public void setViewSize() {
//获取屏幕宽度
Display display= getWindowManager().getDefaultDisplay();
Point point=new Point();
display.getSize(point);
SetUiSize.displayWidth=display.getWidth();
SetUiSize.displayHeight=display.getHeight();
}
@Override
public void setData() {
}
}
3.2、修改工具类的dp宽度值
使用前需要把SetUiSize类前面的displayWidthDp值设置为自己的布局文件宽度值,在布局文件中点击下方图片中的Pixel,鼠标悬浮在Phones按钮上,左边悬浮框在打勾的选项就是布局文件dp尺寸,从左往右小的尺寸就是宽,这里只用到宽就行。
3.3、工具类使用
工具类在使用时要注意,根布局不能设置尺寸,一定要在根布局之下的布局中设置尺寸,根布局设置为自适应或者match_parent,命名要对照对应的设置操作,如下两个方法:setMarginTopRelative和setMarginTopLinear,前面一个是设置当前控件的顶部边距,且父控件为相对布局,后一个类似,只是父控件为线性布局,这里父控件布局会有影响,请使用对应的布局,如果没有的工具方法,请自行添加。除此之外有一点要注意,布局文件中设置字体大小一定要用sp为单位,其它都用dp为单位,否则会计算错误。