常见概念
屏幕尺寸
屏幕尺寸指屏幕的对角线的长度,单位是英寸,1英寸=2.54厘米
屏幕分辨率
屏幕分辨率是指在横纵向上的像素点数,单位是px,1px=1个像素点。一般以纵向像素横向像素,如19601080。
屏幕像素密度
屏幕像素密度是指每英寸上的像素点数,单位是dpi,即“dot per inch”的缩写。屏幕像素密度与屏幕尺寸和屏幕分辨率有关,在单一变化条件下,屏幕尺寸越小、分辨率越高,像素密度越大,反之越小。
dp、dip、dpi、sp、px
- px我们应该是比较熟悉的,前面的分辨率就是用的像素为单位,大多数情况下,比如UI设计、Android原生API都会以px作为统一的计量单位,像是获取屏幕宽高等。
- dip和dp是一个意思,都是Density Independent Pixels的缩写,即密度无关像素,上面我们说过,dpi是屏幕像素密度,假如一英寸里面有160个像素,这个屏幕的像素密度就是160dpi,那么在这种情况下,dp和px如何换算呢?在Android中,规定以160dpi为基准,1dip=1px,如果密度是320dpi,则1dip=2px以此类推。
假如同样都是画一条320px的线,在480800分辨率手机上显示为2/3屏幕宽度,在320480的手机上则占满了全屏,如果使用dp为单位,在这两种分辨率下,160dp都显示为屏幕一半的长度。这也是为什么在Android开发中,写布局的时候要尽量使用dp而不是px的原因。
- sp,即scale-independent pixels,与dp类似,但是可以根据文字大小首选项进行放缩,是设置字体大小的御用单位。
android中的dp在渲染前会将dp转为px,计算公式:
- px = density * dp;
- density = dpi / 160;
- px = dp * (dpi / 160);
获取手机设备密度:
float density=context.getResource().getDisplayMetrics().density;
屏幕尺寸、分辨率、像素密度三者关系
image.png
image.png
目前市面上的屏幕适配方案
- 今日头条的修改设备密度方案
-
最小宽度限定符
现在有screenMatch插件 选中app目录然后点击screenMath
image.png
image.png
在values目录中新建dimens文件将
image
将改文件中的内容全部考到dimens文件中
image.png
将要适配的目录填写 ,剩下的就是要忽略的
然后在执行选中screenMatch文件
最后生成下面文件
image.png
布局中根据尺寸直接写:
image.png
- 自定义适配布局
public class ScreenAdaptationRelaLayout extends LinearLayout {
public ScreenAdaptationRelaLayout(Context context) {
super(context);
}
public ScreenAdaptationRelaLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScreenAdaptationRelaLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
static boolean isFlag = true;
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if(isFlag){
int count = this.getChildCount();
float scaleX = UIUtils.getInstance(this.getContext()).getHorizontalScaleValue();
float scaleY = UIUtils.getInstance(this.getContext()).getVerticalScaleValue();
Log.i("testbarry","x系数:"+scaleX);
Log.i("testbarry","y系数:"+scaleY);
for (int i = 0;i < count;i++){
View child = this.getChildAt(i);
//代表的是当前空间的所有属性列表
LayoutParams layoutParams = (LayoutParams) child.getLayoutParams();
layoutParams.width = (int) (layoutParams.width * scaleX);
layoutParams.height = (int) (layoutParams.height * scaleY);
layoutParams.rightMargin = (int) (layoutParams.rightMargin * scaleX);
layoutParams.leftMargin = (int) (layoutParams.leftMargin * scaleX);
layoutParams.topMargin = (int) (layoutParams.topMargin * scaleY);
layoutParams.bottomMargin = (int) (layoutParams.bottomMargin * scaleY);
}
isFlag = false;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
}
public class UIUtils {
private Context context;
private static UIUtils utils ;
public static UIUtils getInstance(Context context){
if(utils == null){
utils = new UIUtils(context);
}
return utils;
}
//参照宽高
public final float STANDARD_WIDTH = 720;
public final float STANDARD_HEIGHT = 1232;
//当前设备实际宽高
public float displayMetricsWidth ;
public float displayMetricsHeight ;
private final String DIMEN_CLASS = "com.android.internal.R$dimen";
private UIUtils(Context context){
this.context = context;
//
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
//加载当前界面信息
DisplayMetrics displayMetrics = new DisplayMetrics();
windowManager.getDefaultDisplay().getMetrics(displayMetrics);
if(displayMetricsWidth == 0.0f || displayMetricsHeight == 0.0f){
//获取状态框信息
int systemBarHeight = getValue(context,"system_bar_height",48);
if(displayMetrics.widthPixels > displayMetrics.heightPixels){
this.displayMetricsWidth = displayMetrics.heightPixels;
this.displayMetricsHeight = displayMetrics.widthPixels - systemBarHeight;
}else{
this.displayMetricsWidth = displayMetrics.widthPixels;
this.displayMetricsHeight = displayMetrics.heightPixels - systemBarHeight;
}
}
}
//对外提供系数
public float getHorizontalScaleValue(){
return displayMetricsWidth / STANDARD_WIDTH;
}
public float getVerticalScaleValue(){
Log.i("testbarry","displayMetricsHeight:"+displayMetricsHeight);
return displayMetricsHeight / STANDARD_HEIGHT;
}
public int getValue(Context context,String systemid,int defValue) {
try {
Class<?> clazz = Class.forName(DIMEN_CLASS);
Object r = clazz.newInstance();
Field field = clazz.getField(systemid);
int x = (int) field.get(r);
return context.getResources().getDimensionPixelOffset(x);
} catch (Exception e) {
return defValue;
}
}
}
布局中引入:
<com.dongnao.lsn_9_screenadapter.ScreenAdaptationRelaLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="@dimen/dp_150"
android:layout_height="wrap_content"
android:text="test1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<Button
android:layout_width="@dimen/dp_200"
android:layout_height="wrap_content"
android:text="test1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.1" />
<Button
android:layout_width="@dimen/dp_150"
android:layout_height="wrap_content"
android:text="test1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.2" />
<Button
android:layout_width="@dimen/dp_150"
android:layout_height="wrap_content"
android:text="test1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3" />
<Button
android:layout_width="@dimen/dp_150"
android:layout_height="wrap_content"
android:text="test1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.4" />
</com.dongnao.lsn_9_screenadapter.ScreenAdaptationRelaLayout>
- 第三方库的适配方案
https://www.jianshu.com/p/7da141e682c7
https://juejin.im/post/5bce688e6fb9a05cf715d1c2
https://mp.weixin.qq.com/s/d9QCoBP6kV9VSWvVldVVwA












网友评论