1,屏幕分辨率限定符,已经过时了,不在介绍
2,smallestWidth 限定符
使用:(1)android studio中安装ScreenMatch插件;
(2)点击values文件夹下的任意文件,右击,选中ScreenMatch。
生成如下文件
然后移动screenMatch_example_dimens文件到values文件夹下。并修改名字为dimens
右击dimens文件,然后会生成如下
package com.dn_alan.myapplication.pixel;
import android.content.Context;
import android.util.DisplayMetrics;
import android.view.WindowManager;
public class Utils {
private static Utils utils;
private Context mContext;
//这里是设计稿参考宽高,UI设计师按照这个宽高设计
private static final float STANDARD_WIDTH = 1080;
private static final float STANDARD_HEIGHT = 1920;
//这里是屏幕显示宽高,当前屏幕的宽和高
private int mDisplayWidth;
private int mDisplayHeight;
public Utils(Context context) {
mContext = context;
//获取屏幕宽高
if (mDisplayWidth == 0 || mDisplayHeight == 0) {
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
if (windowManager != null) {
//宽高获取
DisplayMetrics displayMetrics = new DisplayMetrics();
//如果不是NavigationBar沉浸式(不包含NavigationBar)
windowManager.getDefaultDisplay().getMetrics(displayMetrics);
// windowManager.getDefaultDisplay().getRealMetrics(displayMetrics);//真实屏幕宽高
//判断当前的横竖屏
if (displayMetrics.widthPixels > displayMetrics.heightPixels) {
//横屏
mDisplayWidth = displayMetrics.heightPixels;
mDisplayHeight = displayMetrics.widthPixels - getStatusBarHeight(context);
} else {
//竖屏
mDisplayWidth = displayMetrics.widthPixels;
mDisplayHeight = displayMetrics.heightPixels - getStatusBarHeight(context);
}
}
}
}
public static Utils getInstance(Context context) {
if (utils == null) {
utils = new Utils(context);
}
return utils;
}
//获取状态栏高度
public int getStatusBarHeight(Context context) {
int resId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
//大于0表示resID存在
if (resId > 0) {
return context.getResources().getDimensionPixelSize(resId);//获取具体的像素值
}
return 0;
}
//获取水平方向的缩放比例
public float getHorizontalScale() {
return mDisplayWidth / STANDARD_WIDTH;
}
//获取垂直方向的缩放比例
public float getVerticalScale() {
return mDisplayHeight / (STANDARD_HEIGHT - getStatusBarHeight(mContext));
}
}
我们重写RelativeLayout布局,重写它的onMeasure();
package com.dn_alan.myapplication.pixel;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.RelativeLayout;
public class ScreenAdapterLayout extends RelativeLayout {
private boolean flag;
public ScreenAdapterLayout(Context context) {
super(context);
}
public ScreenAdapterLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScreenAdapterLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (!flag) { //防止两次测量,onMessasure()执行了两次
flag = true;
//获取横竖方向等比
float scaleX = Utils.getInstance(getContext()).getHorizontalScale();
float scaleY = Utils.getInstance(getContext()).getVerticalScale();
//子View个数
int childCount = getChildCount();
//遍历所有的子View,改变所有的子View的宽和高
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
LayoutParams params = (LayoutParams) child.getLayoutParams();
//当前子View的宽
params.width = (int) (params.width * scaleX);
params.height = (int) (params.height * scaleY);
params.leftMargin = (int) (params.leftMargin * scaleX);
params.rightMargin = (int) (params.rightMargin * scaleX);
params.topMargin = (int) (params.topMargin * scaleY);
params.bottomMargin = (int) (params.bottomMargin * scaleY);
child.setPadding((int) (child.getPaddingLeft() * scaleX), (int) (child.getPaddingTop() * scaleY),
(int) (child.getPaddingRight() * scaleX), (int) (child.getPaddingBottom() * scaleY));
}
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
在布局中可以直接使用px为单位
package com.dn_alan.myapplication.density;
import android.app.Activity;
import android.app.Application;
import android.content.ComponentCallbacks;
import android.content.res.Configuration;
import android.util.DisplayMetrics;
/**
* 修改density,densityDpi值-直接更改系统内部对于目标尺寸而言的像素密度
*/
public class DensityUtils {
private static final float WIDTH = 360;//参考像素密度(dp)
private static float appDensity;//表示屏幕密度
private static float appScaleDensity;//字体缩放比例,默认为appDensity
public static void setDensity(final Application application, Activity activity) {
//获取当前屏幕信息
DisplayMetrics displayMetrics = application.getResources().getDisplayMetrics();
if (appDensity == 0) {
//初始化赋值
appDensity = displayMetrics.density;
appScaleDensity = displayMetrics.scaledDensity;
//监听字体变化
application.registerComponentCallbacks(new ComponentCallbacks() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
//字体发生更改,重新计算scaleDensity
if (newConfig != null && newConfig.fontScale > 0) {
appScaleDensity = application.getResources().getDisplayMetrics().scaledDensity;
}
}
@Override
public void onLowMemory() {
}
});
}
//计算目标density scaledDensity
//屏幕宽度:displayMetrics.widthPixels
float targetDensity = displayMetrics.widthPixels / WIDTH;//1080/360=3;
float targetScaleDensity = targetDensity * (appScaleDensity / appDensity);
int targetDensityDpi = (int) (targetDensity * 160);
//替换Activity的值
//px = dp * (dpi / 160)
DisplayMetrics dm = activity.getResources().getDisplayMetrics();
dm.density = targetDensity; //(dpi/160) 后得到的值
dm.scaledDensity = targetScaleDensity;
dm.densityDpi = targetDensityDpi; //dpi
}
}
package com.dn_alan.myapplication.density;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import com.dn_alan.myapplication.R;
public class DensityActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// //设置density
DensityUtils.setDensity(getApplication(), this);
setContentView(R.layout.activity_density);
}
}