diff --git a/app/src/main/java/com/bonait/bnframework/common/utils/DisplayManager.java b/app/src/main/java/com/bonait/bnframework/common/utils/DisplayManager.java new file mode 100644 index 00000000..9bed0524 --- /dev/null +++ b/app/src/main/java/com/bonait/bnframework/common/utils/DisplayManager.java @@ -0,0 +1,481 @@ +/** + *
+ * Copyright: Copyright (c) 2012 + * Company: ZTE + * Description: 屏幕管理类的实现文件 + *
+ * @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; + } + + /** + * + * 设置参考的样张屏幕密度 + *+ * Description: 设置参考的样张屏幕密度,默认值1.0 + *
+ * @param fDensity 参考屏幕密度 + */ + public static void setReferencedDensity(float fDensity) + { + LogUtils.d(LOG_TAG+ "fDensity=" + fDensity); + mfReferencedScreenDensity = fDensity; + } + + /** + * + * 设置参考的样张字体比重 + *
+ * Description: 设置参考的样张字体比重,默认值1.0 + *
+ * @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; + } + } + + /** + * + * 获取屏幕方向 + *
+ * Description: 获取屏幕方向 + *
+ * @return 屏幕方向 + */ + public static int getScreenOrientation() + { + return miScreenOrientation; + } + + /** + * + * 更新屏幕相关数据 + *
+ * Description: 更新屏幕分辨率、屏幕方向、密度等,每次屏幕参数发生变化,都需要调用更新下。 + *
+ * @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); + } + } + + /** + * + * 更新屏幕相关数据 + *
+ * Description: 更新屏幕分辨率、屏幕方向、密度等,每次屏幕参数发生变化,都需要调用更新下。 + *
+ * @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); + } + } + + /** + * + * 更新屏幕相关数据 + *
+ * Description: 更新屏幕分辨率、屏幕方向、密度等,每次屏幕参数发生变化,都需要调用更新下。 + *
+ */ + 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 + *
+ * Description: 获取屏幕密度 + *
+ * @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; + } + + /** + * + * 遍历全部子控件进行布局适配 + *
+ * Description: 这里用一句话描述这个方法的作用 + *
+ * @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); + } +}