android 不同型号的终端的UI适配--一种解决方法

书写一个管理类,在每一个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;

    /** 字体大小类型 0dp1px */
    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;
    }

    /**
     * 
     * 设置参考的样张屏幕密度
     * 

* Description: 设置参考的样张屏幕密度,默认值1.0 *

* @param fDensity 参考屏幕密度 */ public static void setReferencedDensity(float fDensity) { LogEx.i(LOG_TAG, "fDensity=" + fDensity); mfReferencedScreenDensity = fDensity; } /** * * 设置参考的样张字体比重 *

* Description: 设置参考的样张字体比重,默认值1.0 *

* @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; } } /** * * 获取屏幕方向 *

* 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; LogEx.i(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; LogEx.i(LOG_TAG, "miScreenOrientation=" + miScreenOrientation); updateDisplayInfo(dm); } } /** * * 更新屏幕相关数据 *

* Description: 更新屏幕分辨率、屏幕方向、密度等,每次屏幕参数发生变化,都需要调用更新下。 *

* @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进行等比例缩放; * 其中修改的项涉及widthheightpaddingmargin * 若控件是TextView 或其子类,还会对其字体大小进行缩放, * widthheight使用的是 WRAP_CONTENT 或者 FILL_PARENT ,则widthheight不会被缩放。 * * @param view 需要进行缩放的的视图 */ public static void scaleView(View view) { if (null != view) { scaleView(view, mfDeviceScaleRate); } else { LogEx.w(LOG_TAG, "scaleView : view is null"); } } /** * * 选取最小比例fRateview进行等比例缩放; * 其中修改的项涉及widthheightpaddingmargin * 若控件是TextView 或其子类,还会对其字体大小进行缩放, * widthheight使用的是 WRAP_CONTENT 或者 FILL_PARENT ,则widthheight不会被缩放。 * @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 *

* Description: 获取屏幕密度 *

* @return */ public static float getScreenDensity() { return mfScreenDensity; } public static double getWidthScaleRate() { return mfWidthScaleRate; } public static double getHeightScaleRate() { return mfHeightScaleRate; } /** * * 设置 字体大小类型 0dp1px ,默认dp * @date * @author * @param iTextSizeType 0dp1px */ 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); } } } }

使用方法:

activity初始化:

DisplayManager.setReferenceMaxWidthHeight(480, 800);
DisplayManager.updateDisplayInfo(this);

控件的适配:

DisplayManager.scaleView(mReplyList);
DisplayManager.scaleView(mImgClose);
DisplayManager.scaleView(mTxtCommentName);
DisplayManager.scaleView(mTxtCommentTime);
DisplayManager.scaleView(mTxtCommentTxt);


你可能感兴趣的:(Android开发)