屏幕适配之_density 适配

264 阅读2分钟
 protected float initScaledDensity() {
    //适配字体缩放密度
    int width = getResources().getDimensionPixelSize(R.dimen.design_width);
    int single_chinese_width = getResources().getDimensionPixelSize(R.dimen.design_single_chinese_width);
    int sp_value = getResources().getDimensionPixelSize(R.dimen.design_sp_value);
    //计算设计图的汉字px/sp值的比例
    float designScaleDensity = (float) single_chinese_width / (float) sp_value;

    //计算屏幕相对设计图的放大比例
    float widthScale = (float) DensityUtil.getScreenW(App.this) / (float) width;

    //得出px/sp 比
    return widthScale * designScaleDensity;
  }



package com.xincheng.lib.framework.base;

import android.app.Activity;
import android.app.Application;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;

import com.xincheng.lib.utils.ScreenUtil;

public abstract class BaseApp extends Application {

  private static float originScaledDensity = 0.0f;
  private static float scaledDensity;
  private static int densityDpi;


  @Override
  public void onCreate() {
    super.onCreate();
    originScaledDensity = getResources().getDisplayMetrics().scaledDensity;
    scaledDensity = initScaledDensity();
    densityDpi = getDensityDpi();
    ActivityLifecycleCallbacks activityLifecycleCallbacks = new ActivityLifecycleCallbacks() {

      @Override
      public void onActivityCreated(Activity activity, Bundle savedInstanceState) {

        ScreenUtil.adapterFontAndDrawable(activity, scaledDensity, densityDpi);

        if (activity instanceof FragmentActivity) {
          FragmentManager.FragmentLifecycleCallbacks fragmentLifecycleCallbacks = new FragmentManager.FragmentLifecycleCallbacks() {
            @Override
            public void onFragmentCreated(@NonNull FragmentManager fm, @NonNull Fragment f,
                @Nullable Bundle savedInstanceState) {
              super.onFragmentCreated(fm, f, savedInstanceState);
              ScreenUtil.adapterFontAndDrawable(f, scaledDensity, densityDpi);
            }
          };

          FragmentActivity fragmentActivity = (FragmentActivity) activity;
          fragmentActivity.getSupportFragmentManager().registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, true);
        }

      }

      @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) {
      }
    };
    registerActivityLifecycleCallbacks(activityLifecycleCallbacks);

  }

  /**
   * 用于获取自定义字体密度
   *
   * @return scaledDensity
   */
  protected abstract float initScaledDensity();

  protected abstract int getDensityDpi();

  public static float getOriginScaledDensity() {
    return originScaledDensity;
  }

  public static float getScaledDensity() {
    return scaledDensity;
  }

}








package com.xincheng.lib.utils;

import android.app.Activity;
import android.content.res.Resources;
import android.util.DisplayMetrics;

import androidx.fragment.app.Fragment;

public class ScreenUtil {

  /**
   * 如果不同目录下都有资源 ,则根据densityDpi选取: ~160: mdpi  ~240:hdpi   ~320:xhdpi  ~480:xxhdpi  ~640:xxxhdpi
   * <p>
   * 如果对应目录没有资源,检索顺序为 更高密度目录->nodpi->更低目录
   * <p>
   * 然后根据进行densityDpi缩放
   * 资源缩放:例如:屏幕densityDpi = 230 (对应~240:hdpi),资源放在mipmap-mdpi中, ,则图片宽高缩放:scale=230/160
   * 例如:屏幕densityDpi = 230 (对应~240:hdpi),资源放在mipmap-hdpi中, ,则图片宽高缩放:scale=230/240
   * (网络上说的找到对应目录的资源就不进行缩放,根据实测是错的,只有drawable-nodpi是不缩放的)
   */

  public static void adapterFontAndDrawable(Activity activity, float scaledDensity, int densityDpi) {
    //activity的屏幕尺寸
    DisplayMetrics activityDM = activity.getResources().getDisplayMetrics();
    // 适配相应比例的字体大小
    Logger.e("url origin densityDpi=" + activityDM.densityDpi + ", density=" + activityDM.density + ", scaledDensity="
        + activityDM.scaledDensity);

    activityDM.scaledDensity = scaledDensity;

    //统一用hdpi的资源,防止资源被缩放
    activityDM.densityDpi = densityDpi;


  }


  public static void adapterFontAndDrawable(Fragment fragment, float scaledDensity, int densityDpi) {

    //activity的屏幕尺寸
    DisplayMetrics activityDM = fragment.getResources().getDisplayMetrics();
    Logger.e("url origin densityDpi=" + activityDM.densityDpi + ", density=" + activityDM.density + ", scaledDensity="
        + activityDM.scaledDensity);
    // 适配相应比例的字体大小
    activityDM.scaledDensity = scaledDensity;
    //统一用hdpi的资源,防止资源被缩放
    activityDM.densityDpi = densityDpi;

  }

  public static void adapterScreen(Activity activity, int targetDP, boolean isVertical) {
    //系统的屏幕尺寸
    DisplayMetrics systemDM = Resources.getSystem().getDisplayMetrics();
    //app整体的屏幕尺寸
    DisplayMetrics appDM = activity.getApplication().getResources().getDisplayMetrics();
    //activity的屏幕尺寸
    DisplayMetrics activityDM = activity.getResources().getDisplayMetrics();

    if (isVertical) {
      // 适配屏幕的高度
      activityDM.density = activityDM.heightPixels / (float) targetDP;
    } else {
      // 适配屏幕的宽度
      activityDM.density = activityDM.widthPixels / (float) targetDP;
    }
    // 适配相应比例的字体大小
    activityDM.scaledDensity = activityDM.density * (systemDM.scaledDensity / systemDM.density);
    // 适配dpi
    activityDM.densityDpi = (int) (160 * activityDM.density);
  }

  public static void resetScreen(Activity activity) {
    //系统的屏幕尺寸
    DisplayMetrics systemDM = Resources.getSystem().getDisplayMetrics();
    //app整体的屏幕尺寸
    DisplayMetrics appDM = activity.getApplication().getResources().getDisplayMetrics();
    //activity的屏幕尺寸
    DisplayMetrics activityDM = activity.getResources().getDisplayMetrics();

    activityDM.density = systemDM.density;
    activityDM.scaledDensity = systemDM.scaledDensity;
    activityDM.densityDpi = systemDM.densityDpi;

    appDM.density = systemDM.density;
    appDM.scaledDensity = systemDM.scaledDensity;
    appDM.densityDpi = systemDM.densityDpi;
  }

}