Browse Source

屏幕适配工具

调味吧台
liup 7 months ago
parent
commit
b4f9100c71
1 changed files with 481 additions and 0 deletions
  1. +481
    -0
      app/src/main/java/com/bonait/bnframework/common/utils/DisplayManager.java

+ 481
- 0
app/src/main/java/com/bonait/bnframework/common/utils/DisplayManager.java View File

@@ -0,0 +1,481 @@
/**
* <p>
* Copyright: Copyright (c) 2012
* Company: ZTE
* Description: 屏幕管理类的实现文件
* </p>
* @Title DisplayManager.java
* @Package com.zte.iptvclient.android.ui
* @version 1.0
* @author jamesqiao10065075
* @date 2012-3-3
*/
package com.bonait.bnframework.common.utils;


import android.app.Activity;
import android.app.Service;
import android.content.pm.ActivityInfo;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.apkfuns.logutils.LogUtils;


/**
* 屏幕管理类
* @ClassName:DisplayManager
* @Description: 管理屏幕相关的内容,包括宽度和高度像素值。需要在应用刚启动时的第一个Activity中初始化下。
* @author:
*
*/
public class DisplayManager
{
/** 日志标签 */
private final static String LOG_TAG = "DisplayManager";

/******************************参考的屏幕数据***************************/

/** 参照分辨率 */
private static int miReferencedMaxWidth = 800;
/** 参照分辨率 */
private static int miReferencedMaxHeight = 1208;

/** 参照屏幕密度,基于160dpi */
private static float mfReferencedScreenDensity = 1.0f;
/** 参照字体缩放比重 */
private static float mfReferencedFontDensity = 1.0f;

/******************************实际的屏幕数据***************************/
/** 宽度 */
private static int miDisplayWidth = 1280;
/** 高度 */
private static int miDisplayHeight = 752;

/** 屏幕密度 */
private static float mfScreenDensity = 1.0f;

/** 当前系统设置字体密度 */
private static float mfFontDensity = 1.0f;

/** 屏幕方向 */
private static int miScreenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;

/******************************计算的屏幕数据***************************/
/** 设备屏幕相对标准屏幕伸缩比例 */
private static float mfDeviceScaleRate = 1.0f;

/** 相对标准屏幕,此设备水平拉伸比率 */
private static double mfWidthScaleRate = 1.0f;

/** 相对标准屏幕,此设备高度拉伸比率 */
private static double mfHeightScaleRate = 1.0f;

/** 是否需要缩放 */
private static boolean mbNeedScaleView = false;

/** 字体大小类型 0:dp,1:px */
private static int mTextSizeType = 0;

/**
*
* 设置参考的样张屏幕分辨率最大宽度和高度
* @param iMaxWidth 样张屏幕分辨率最大宽度
* @param iMaxHeight 样张屏幕分辨率最大高度
*/
public static void setReferenceMaxWidthHeight(int iMaxWidth, int iMaxHeight)
{
LogUtils.d(LOG_TAG+ "iMaxWidth=" + iMaxWidth + ",iMaxHeight=" + iMaxHeight);
LogUtils.d(LOG_TAG+"iMaxWidth=" + iMaxWidth + ",iMaxHeight=" + iMaxHeight);
miReferencedMaxWidth = iMaxWidth;
miReferencedMaxHeight = iMaxHeight;
}

/**
*
* 设置参考的样张屏幕密度
* <p>
* Description: 设置参考的样张屏幕密度,默认值1.0
* <p>
* @param fDensity 参考屏幕密度
*/
public static void setReferencedDensity(float fDensity)
{
LogUtils.d(LOG_TAG+ "fDensity=" + fDensity);
mfReferencedScreenDensity = fDensity;
}

/**
*
* 设置参考的样张字体比重
* <p>
* Description: 设置参考的样张字体比重,默认值1.0
* <p>
* @param fDensity 参考字体比重
*/
public static void setReferencedScaledDensity(float fDensity)
{
LogUtils.d(LOG_TAG+ "fDensity=" + fDensity);
mfReferencedFontDensity = fDensity;
}

/**
*
* 获取屏幕宽度(像素)
* @return 宽度像素值
*/
public static int getDisplayWidth()
{
return miDisplayWidth;
}

/**
*
* 获取屏幕高度(像素)
* @return 高度像素值
*/
public static int getDisplayHeight()
{
return miDisplayHeight;
}

/**
*
* 根据px像素值换算成对应的dip值。
* @param iPXValue 像素值
* @return DIP对应的值
*/
public static int getDipValueByPX(int iPXValue)
{
return iPXValue;
}

/**
* 获取换算后的宽度,以最大分辨率及样张的图上的参考宽度来换算。
* @param iReferenceWidth 参考宽度(像素)
* @return 实际屏幕上的宽度(像素)
*/
public static int getRealWidth(int iReferenceWidth)
{
if (miReferencedMaxWidth > 0)
{
//此处计算去除屏幕密度,等同于传入的值的单位是dp
return (int) ((iReferenceWidth * miDisplayWidth) / (miReferencedMaxWidth/* * mfScreenDensity*/));
}
else
{
LogUtils.w(LOG_TAG+ "Invalid miReferencedMaxWidth=" + miReferencedMaxWidth);
return 0;
}
}

/**
* 获取换算后的高度, 以最大分辨率及样张的图上的参考高度来换算。
* @param iReferenceHeight 参考高度(像素)
* @return 实际屏幕上的高度(像素)
*/
public static int getRealHeight(int iReferenceHeight)
{
if (miReferencedMaxHeight > 0)
{
//此处计算去除屏幕密度,等同于传入的值的单位是dp
return (int) ((iReferenceHeight * miDisplayHeight) / (miReferencedMaxHeight/* * mfScreenDensity*/));
}
else
{
LogUtils.w(LOG_TAG+ "Invalid miReferencedMaxHeight=" + miReferencedMaxHeight);
return 0;
}
}

/**
*
* 获取屏幕方向
* <p>
* Description: 获取屏幕方向
* <p>
* @return 屏幕方向
*/
public static int getScreenOrientation()
{
return miScreenOrientation;
}

/**
*
* 更新屏幕相关数据
* <p>
* Description: 更新屏幕分辨率、屏幕方向、密度等,每次屏幕参数发生变化,都需要调用更新下。
* <p>
* @param activity 活动窗口
*/
public static void updateDisplayInfo(Activity activity)
{
if (null != activity)
{
//获取分辨率等信息
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);

//更新当前屏幕方向
miScreenOrientation = activity.getResources().getConfiguration().orientation;
LogUtils.d(LOG_TAG+ "miScreenOrientation=" + miScreenOrientation);

updateDisplayInfo(dm);
}
}

/**
*
* 更新屏幕相关数据
* <p>
* Description: 更新屏幕分辨率、屏幕方向、密度等,每次屏幕参数发生变化,都需要调用更新下。
* <p>
* @param service 服务
*/
public static void updateDisplayInfo(Service service)
{
if (null != service)
{
//获取分辨率等信息
DisplayMetrics dm = service.getResources().getDisplayMetrics();

//更新当前屏幕方向
miScreenOrientation = service.getResources().getConfiguration().orientation;
LogUtils.d(LOG_TAG+ "miScreenOrientation=" + miScreenOrientation);

updateDisplayInfo(dm);
}
}

/**
*
* 更新屏幕相关数据
* <p>
* Description: 更新屏幕分辨率、屏幕方向、密度等,每次屏幕参数发生变化,都需要调用更新下。
* <p>
*/
private static void updateDisplayInfo(DisplayMetrics dm)
{
miDisplayWidth = dm.widthPixels;
miDisplayHeight = dm.heightPixels;

LogUtils.d(LOG_TAG+ "miDisplayWidth=" + miDisplayWidth + ",miDisplayHeight="
+ miDisplayHeight);

mfFontDensity = dm.scaledDensity;
LogUtils.d(LOG_TAG+ "mfFontDensity=" + mfFontDensity);

mfScreenDensity = dm.density;
LogUtils.d(LOG_TAG+ "mfScreenDensity=" + mfScreenDensity);

LogUtils.d(LOG_TAG+ "densityDpi=" + dm.densityDpi);

mbNeedScaleView = false;
//判断是否需要缩放(宽、高、屏幕密度、字体密度)
if (miDisplayWidth != miReferencedMaxWidth
|| miDisplayHeight != miReferencedMaxHeight
|| Math.abs(mfScreenDensity - mfReferencedScreenDensity) >= 0.001
|| Math.abs(mfFontDensity - mfReferencedFontDensity) >= 0.001)
{
mbNeedScaleView = true;
}

//宽度的缩放比例
mfWidthScaleRate = 1.0f;
if (miReferencedMaxWidth > 0)
{
mfWidthScaleRate = 1.0 * miDisplayWidth
/ (miReferencedMaxWidth * mfScreenDensity / mfReferencedScreenDensity);
LogUtils.d(LOG_TAG+ "mfWidthScaleRate=" + mfWidthScaleRate);
}

//高度的缩放比例
mfHeightScaleRate = 1.0f;
if (miReferencedMaxHeight > 0)
{
mfHeightScaleRate = 1.0 * miDisplayHeight
/ (miReferencedMaxHeight * mfScreenDensity / mfReferencedScreenDensity);
LogUtils.d(LOG_TAG+ "mfHeightScaleRate=" + mfHeightScaleRate);
}

//取较小者
mfDeviceScaleRate = (float) (mfWidthScaleRate < mfHeightScaleRate
? mfWidthScaleRate
: mfHeightScaleRate);

LogUtils.d(LOG_TAG+ "mfDeviceScaleRate=" + mfDeviceScaleRate);

//缩放比例为1,则不需要进行比例缩放处理
if (Math.abs(mfDeviceScaleRate - 1.0) <= 0.001)
{
mbNeedScaleView = false;
}

LogUtils.d(LOG_TAG+ "mbNeedScaleView=" + mbNeedScaleView);
}

/**
*
* 根据当前设备与标准设备其高度和宽度的比例,选取最小比例(mfDeviceScaleRate)对view进行等比例缩放;
* 其中修改的项涉及width,height,padding,margin,
* 若控件是TextView 或其子类,还会对其字体大小进行缩放,
* 若width,height使用的是 WRAP_CONTENT 或者 FILL_PARENT ,则width,height不会被缩放。
* @param view 需要进行缩放的的视图
*/
public static void scaleView(View view)
{
if (null != view)
{
// scaleView(view, mfDeviceScaleRate);
scaleView(view, (float) mfWidthScaleRate);
}
else
{
LogUtils.w(LOG_TAG+"scaleView : view is null");
}
}

/**
*
* 选取最小比例fRate对view进行等比例缩放;
* 其中修改的项涉及width,height,padding,margin,
* 若控件是TextView 或其子类,还会对其字体大小进行缩放,
* 若width,height使用的是 WRAP_CONTENT 或者 FILL_PARENT ,则width,height不会被缩放。
* @param view 需要进行缩放的的视图
* @param fRate 缩放比例
*/
public static void scaleView(View view, float fRate)
{
if (!mbNeedScaleView || view == null || fRate <= 0.001)
{
return;
}

//对TextView的字体大小单独处理
if (view instanceof TextView)
{
TextView txtView = (TextView) view;

//默认dp
float f = (float) (txtView.getTextSize() * fRate/** mfScreenDensity*/
/ mfFontDensity);
if (mTextSizeType == 1) //px
{
f = (float) (txtView.getTextSize() * fRate * mfScreenDensity / mfFontDensity);
}

txtView.setTextSize(f);
}

ViewGroup.LayoutParams params = (ViewGroup.LayoutParams) view.getLayoutParams();
if (null != params)
{
//Width & Height
if (params.width != ViewGroup.LayoutParams.WRAP_CONTENT
&& params.width != ViewGroup.LayoutParams.MATCH_PARENT)
{
params.width = (int) (params.width * fRate + 0.5f);
}

if (params.height != ViewGroup.LayoutParams.WRAP_CONTENT
&& params.height != ViewGroup.LayoutParams.MATCH_PARENT)
{
params.height = (int) (params.height * fRate + 0.5f);
}

//Padding
view.setPadding((int) (view.getPaddingLeft() * fRate + 0.5f),
(int) (view.getPaddingTop() * fRate + 0.5f),
(int) (view.getPaddingRight() * fRate + 0.5f),
(int) (view.getPaddingBottom() * fRate + 0.5f));
}

//Margin
ViewGroup.MarginLayoutParams params2 = (ViewGroup.MarginLayoutParams) view
.getLayoutParams();
if (params2 != null)
{
params2.setMarginStart((int) (params2.getMarginStart() * fRate));
params2.setMarginEnd((int) (params2.getMarginEnd() * fRate));
params2.leftMargin *= fRate;
params2.rightMargin *= fRate;
params2.topMargin *= fRate;
params2.bottomMargin *= fRate;
}
}

/**
* getScreenDensity
* <p>
* Description: 获取屏幕密度
* <p>
* @return
*/
public static float getScreenDensity()
{
return mfScreenDensity;
}

public static double getWidthScaleRate()
{
return mfWidthScaleRate;
}

public static double getHeightScaleRate()
{
return mfHeightScaleRate;
}

/**
*
* 设置 字体大小类型 0:dp,1:px ,默认dp
* @param iTextSizeType 0:dp,1:px
*/
public static void setTextSizeType(int iTextSizeType)
{
mTextSizeType = iTextSizeType;
}

/**
*
* 遍历全部子控件进行布局适配
* <p>
* Description: 这里用一句话描述这个方法的作用
* <p>
* @param root
*/
public static void scaleViewGroup(ViewGroup root)
{
for (int i = 0, n = root.getChildCount(); i < n; i++)
{
View v = root.getChildAt(i);

scaleView(v);

if (v instanceof ViewGroup)
{
scaleViewGroup((ViewGroup) v);
}
}
}

/**
* 判断是否需要缩放 避免adapter重绘时多次缩放
* @param view
* @return
*/
public static boolean shouldScale(TextView view){
if(view.getTextSize()> 34 || view.getTextSize()< 30){
return true;
}
return false;
}

public static void scaleViewRemote(View view)
{
scaleView(view,(float) mfDeviceScaleRate);
}
}

Loading…
Cancel
Save