书写一个管理类,在每一个activity加载的时候初始化这个管理类,然后在控件创建绑定的时候去调用方法适配每一个控件view。
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.Button;
import android.widget.EditText;
import android.widget.TextView;
/**
* 屏幕管理类
* @ClassName:DisplayManager
* @Description: 管理屏幕相关的内容,包括宽度和高度像素值。需要在应用刚启动时的第一个Activity中初始化下。
* @author:
* @date:
*
*/
public class DisplayManager
{
/** 日志标签 */
private final static String LOG_TAG = "DisplayManager";
/******************************参考的屏幕数据***************************/
/** 参照分辨率 */
private static int miReferencedMaxWidth = 1280;
/** 参照分辨率 */
private static int miReferencedMaxHeight = 752;
/** 参照屏幕密度,基于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)
{
LogEx.i(LOG_TAG, "iMaxWidth=" + iMaxWidth + ",iMaxHeight=" + iMaxHeight);
miReferencedMaxWidth = iMaxWidth;
miReferencedMaxHeight = iMaxHeight;
}
/**
*
* 设置参考的样张屏幕密度
* <p>
* Description: 设置参考的样张屏幕密度,默认值1.0
* <p>
* @param fDensity 参考屏幕密度
*/
public static void setReferencedDensity(float fDensity)
{
LogEx.i(LOG_TAG, "fDensity=" + fDensity);
mfReferencedScreenDensity = fDensity;
}
/**
*
* 设置参考的样张字体比重
* <p>
* Description: 设置参考的样张字体比重,默认值1.0
* <p>
* @param fDensity 参考字体比重
*/
public static void setReferencedScaledDensity(float fDensity)
{
LogEx.i(LOG_TAG, "fDensity=" + fDensity);
mfReferencedFontDensity = fDensity;
}
/**
*
* 获取屏幕宽度(像素)
* @date
* @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;
}
/**
* 获取换算后的宽度,以最大分辨率及样张的图上的参考宽度来换算。
* @date
* @param iReferenceWidth 参考宽度(像素)
* @return 实际屏幕上的宽度(像素)
*/
public static int getRealWidth(int iReferenceWidth)
{
if (miReferencedMaxWidth > 0)
{
//此处计算去除屏幕密度,等同于传入的值的单位是dp
return (int) ((iReferenceWidth * miDisplayWidth) / (miReferencedMaxWidth/* * mfScreenDensity*/));
}
else
{
LogEx.w(LOG_TAG, "Invalid miReferencedMaxWidth=" + miReferencedMaxWidth);
return 0;
}
}
/**
* 获取换算后的高度, 以最大分辨率及样张的图上的参考高度来换算。
* @date
* @param iReferenceHeight 参考高度(像素)
* @return 实际屏幕上的高度(像素)
*/
public static int getRealHeight(int iReferenceHeight)
{
if (miReferencedMaxHeight > 0)
{
//此处计算去除屏幕密度,等同于传入的值的单位是dp
return (int) ((iReferenceHeight * miDisplayHeight) / (miReferencedMaxHeight/* * mfScreenDensity*/));
}
else
{
LogEx.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;
LogEx.i(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;
LogEx.i(LOG_TAG, "miScreenOrientation=" + miScreenOrientation);
updateDisplayInfo(dm);
}
}
/**
*
* 更新屏幕相关数据
* <p>
* Description: 更新屏幕分辨率、屏幕方向、密度等,每次屏幕参数发生变化,都需要调用更新下。
* <p>
* @param activity 活动窗口
*/
private static void updateDisplayInfo(DisplayMetrics dm)
{
miDisplayWidth = dm.widthPixels;
miDisplayHeight = dm.heightPixels;
LogEx.i(LOG_TAG, "miDisplayWidth=" + miDisplayWidth + ",miDisplayHeight="
+ miDisplayHeight);
mfFontDensity = dm.scaledDensity;
LogEx.i(LOG_TAG, "mfFontDensity=" + mfFontDensity);
mfScreenDensity = dm.density;
LogEx.i(LOG_TAG, "mfScreenDensity=" + mfScreenDensity);
LogEx.i(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);
LogEx.i(LOG_TAG, "mfWidthScaleRate=" + mfWidthScaleRate);
}
//高度的缩放比例
mfHeightScaleRate = 1.0f;
if (miReferencedMaxHeight > 0)
{
mfHeightScaleRate = 1.0 * miDisplayHeight
/ (miReferencedMaxHeight * mfScreenDensity / mfReferencedScreenDensity);
LogEx.i(LOG_TAG, "mfHeightScaleRate=" + mfHeightScaleRate);
}
//取较小者
mfDeviceScaleRate = (float) (mfWidthScaleRate < mfHeightScaleRate
? mfWidthScaleRate
: mfHeightScaleRate);
LogEx.i(LOG_TAG, "mfDeviceScaleRate=" + mfDeviceScaleRate);
//缩放比例为1,则不需要进行比例缩放处理
if (Math.abs(mfDeviceScaleRate - 1.0) <= 0.001)
{
mbNeedScaleView = false;
}
LogEx.i(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);
}
else
{
LogEx.w(LOG_TAG, "scaleView : view is null");
}
}
/**
*
* 选取最小比例fRate对view进行等比例缩放;
* 其中修改的项涉及width,height,padding,margin,
* 若控件是TextView 或其子类,还会对其字体大小进行缩放,
* 若width,height使用的是 WRAP_CONTENT 或者 FILL_PARENT ,则width,height不会被缩放。
* @date
* @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.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
* @date
* @author
* @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);
}
}
}
}
使用方法: activity初始化:
DisplayManager.setReferenceMaxWidthHeight(480, 800);
DisplayManager.updateDisplayInfo(this);
控件的适配:
DisplayManager.scaleView(mReplyList);
DisplayManager.scaleView(mImgClose);
DisplayManager.scaleView(mTxtCommentName);
DisplayManager.scaleView(mTxtCommentTime);
DisplayManager.scaleView(mTxtCommentTxt);