Android屏幕适配字体适配

首先来看一下他们的基本概念:

px   :是屏幕的像素点
dp   :一个基于density的抽象单位,如果一个160dpi的屏幕,1dp=1px
dip  :等同于dp
sp   :同dp相似,但还会根据用户的字体大小偏好来缩放(建议使用sp作为文本的单位,其它用dip)

 

针对dip和px 的关系,做以下概述:

1). px (pixels)像素 :

一个像素通常被视为图像的最小的完整采样,这个用的比较多,特别是web开发,页面基本都是使用像素作为单位的.

2). dip或dp (device independent pixels):

设备独立像素 — 这个和设备硬件有关,一般我们为了支持手机上多种分辨率,如WVGA、HVGA

和QVGA,都会使用dip作为长度的单位

下面来看一下手机屏幕类型和密度以及分辨率的对应关系

QVGA屏density=120         QVGA(240*320)
HVGA屏density=160         HVGA(320*480)
WVGA屏density=240        WVGA(480*800)
WQVGA屏density=120      WQVGA(240*400)

 

注:density值表示每英寸有多少个显示点,与分辨率是两个概念。

 

不同density下屏幕分辨率信息是不同的,以480dip*800dip的 WVGA(density=240)为例

1、当density=120时 

转化:转化系数=120/240

屏幕实际分辨率为240px*400px (两个点对应一个分辨率)

状态栏和标题栏高各19px或者25dip

横屏是屏幕宽度400px 或者800dip,工作区域高度211px或者480dip

竖屏时屏幕宽度240px或者480dip,工作区域高度381px或者775dip

2、当density=160时 

转化:转化系数=160/240

屏幕实际分辨率为320px*533px (3个点对应两个分辨率)

状态栏和标题栏高个25px或者25dip

横屏是屏幕宽度533px 或者800dip,工作区域高度295px或者480dip

竖屏时屏幕宽度320px或者480dip,工作区域高度508px或者775dip

3、当density=240时 

转化:转化系数=240/240

屏幕实际分辨率为480px*800px (一个点对于一个分辨率)

状态栏和标题栏高个38px或者25dip

横屏是屏幕宽度800px 或者800dip,工作区域高度442px或者480dip

竖屏时屏幕宽度480px或者480dip,工作区域高度762px或者775dip

我们一般在项目中会定义多个适配资源文件夹(values-XXX,drawable-XXX等)

drawable-ldpi:     屏幕密度为120的手机设备

drawable-mdpi:   屏幕密度为160的手机设备(此为baseline,其他均以此为基准,在此设备上,1dp = 1px)

drawable-hdpi:    屏幕密度为240的手机设备

drawable-xhdpi:  屏幕密度为320的手机设备

drawable-xxhdpi:屏幕密度为480的手机设备

(values也是一样,当然还有一点要注意:values和values-hdpi效果是一样的,drawable和drawable-hdpi效果也是一样的,所以一般我们都会在这两个文件夹中存放的值是一样的,如果两个都有的话,适配更好)


apk的资源包中

当屏幕density=240时,使用hdpi 标签的资源

当屏幕density=160时,使用mdpi标签的资源

当屏幕density=120时,使用ldpi标签的资源

当屏幕density=320时,使用xhdpi标签的资源

当屏幕density=480时,使用xxhdpi标签的资源

不加任何标签的资源是各种分辨率情况下共用的

所以布局时尽量使用单位dip,少使用px

dp与px换算公式:
pixs =dips * (densityDpi/160). 
dips=(pixs*160)/densityDpi

但是我们在代码里面进行转化的时候还需要有一个偏移值:0.5f

private static final float scale = mContext.getResources().getDisplayMetrics().density;
 
private static final float scaledDensity = mContext.mContext.getResources().getDisplayMetrics().scaledDensity;
 
/**
 * dp转成px
 * @param dipValue
 * @return
 */
public static int dip2px(float dipValue) {
	return (int) (dipValue * scale + 0.5f);
}
 
/**
 * px转成dp
 * @param pxValue
 * @return
 */
public static int px2dip(float pxValue) {
	return (int) (pxValue / scale + 0.5f);
}
 
/**
 * sp转成px
 * @param spValue
 * @param type
 * @return
 */
public static float sp2px(float spValue, int type) {
	switch (type) {
	case CHINESE:
		return spValue * scaledDensity;
	case NUMBER_OR_CHARACTER:
		return spValue * scaledDensity * 10.0f / 18.0f;
	default:
		return spValue * scaledDensity;
	}
}

我们看到,这里的scale是在这个类DisplayMetrics中定义的全局变量,其实这个值就是当前手机的density/160,scaleDensity是用来px和sp之间的转化和scale差不多。还有一点就是这里转化都会有一个偏移值处理

以上转载自:https://blog.csdn.net/jiangwei0910410003/article/details/40509571

=======================================分割线====================================

安卓屏幕适配 项目直接用dp和sp的可以不用改动 直接加入一句代码即可实现适配

还未确定会不会有兼容性问题和性能问题 需要时间测试

目前测试过模拟器的不同分辨率和不同dpi基本效果不会差太多

旋转屏幕 布局会按横版的大小缩放 视图也不会乱

package com.dzw.demo.utils;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.graphics.Point;
import android.os.Bundle;
import android.view.WindowManager;

import static android.content.Context.WINDOW_SERVICE;

public class ScreenAdaptation {

    private Application.ActivityLifecycleCallbacks activityLifecycleCallbacks;

    private Application mApplication;

    private float mWidth = 720;

    private float mHeight = 1280;

    public ScreenAdaptation(Application application, float width, int height) {

        mApplication = application;

        mWidth = width;

        mHeight = height;

        activityLifecycleCallbacks = new Application.ActivityLifecycleCallbacks() {

            @Override

            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {


                //开启Activity才执行

                resetDensity(activity, mWidth, mHeight);

            }

            @Override

            public void onActivityStarted(Activity activity) {

            }

            @Override

            public void onActivityResumed(Activity activity) {

            }

            @Override

            public void onActivityPaused(Activity activity) {

            }

            @Override

            public void onActivityStopped(Activity activity) {

            }

            @Override

            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

            }

            @Override

            public void onActivityDestroyed(Activity activity) {

            }

        };

    }

    /**
     * 注册
     */

    public void register() {

        resetDensity(mApplication, mWidth, mHeight);

        mApplication.registerActivityLifecycleCallbacks(activityLifecycleCallbacks);

    }

    /**
     * 注销
     */

    public void unregister() {
        //设置为默认

        mApplication.getResources().getDisplayMetrics().setToDefaults();

        mApplication.unregisterActivityLifecycleCallbacks(activityLifecycleCallbacks);

    }

    /**
     * dp适配getResources().getDisplayMetrics().density
     * <p>
     * sp适配getResources().getDisplayMetrics().scaledDensity
     * <p>
     * pt适配getResources().getDisplayMetrics().xdpi
     *
     * @paramcontext
     * @paramwidthui设计图的宽度
     * @paramheightui设计图的高度
     */

    private static void resetDensity(Context context, float width, float height) {

        Point point = new Point();


        //获取屏幕的数值

        ((WindowManager) context.getSystemService(WINDOW_SERVICE)).getDefaultDisplay().getSize(point);


        //dp适配getResources().getDisplayMetrics().density

        context.getResources().getDisplayMetrics().density = point.x / width * 2f;

        context.getResources().getDisplayMetrics().density = point.y / height * 2f;


        //sp适配getResources().getDisplayMetrics().scaledDensity

        context.getResources().getDisplayMetrics().scaledDensity = point.x / width * 2f;

        context.getResources().getDisplayMetrics().scaledDensity = point.y / height * 2f;

    }

}

 

在Application的onCreate中调用:

new ScreenAdaptation(this,720,1280).register();

以上转载自:https://www.jianshu.com/p/97b107308923

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值