Androidスクリーンの最適化--ピクセルのスケールをカスタマイズしてスクリーンの最適化を実現

4653 ワード

Androidスクリーン対応–ピクセルのスケールをカスタマイズしてスクリーン対応を実現
Androidのアダプティブでは、ピクセルのスケールを計算することでアダプティブなレイアウトをカスタマイズできます.大まかな考え方は、デバイスの実際のアスペクト画素値を取得して参照デバイスのアスペクト値で除算することによって、このスケール値を得ることで、コントロールのアスペクト値を設定する際に、開発者が指定したアスペクト値にこのスケール値を乗じて、コントロールの実際の表示サイズを得ることができ、式は大体以下の通りである.scaleX = / = * scaleX
実現方案は以下の通りである.
まず,X方向とY方向のデバイスの画素値の割合をツールクラスで取得した.
public class PixelUtils {

    private Context mContext;
    private static PixelUtils mUtils;

    //    
    private float mWidth;
    private float mHeight;

    //         ,       px
    private float STANDARD_WIDTH = 720;
    private float STANDARD_HEIGHT = 1080;
    public PixelUtils(Context context) {
        mContext = context;
        WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        if(manager != null){
            DisplayMetrics metrics = new DisplayMetrics();
            manager.getDefaultDisplay().getMetrics(metrics);    //       Metrics  
            if(metrics.widthPixels > metrics.heightPixels){
                //  ,      
                mWidth = metrics.heightPixels;
                mHeight = metrics.widthPixels;
            }else{
                //  
                mWidth = metrics.widthPixels;
                mHeight = metrics.heightPixels;
            }
        }
    }

    public static PixelUtils getInstance(Context context){
        if(mUtils == null){
            mUtils = new PixelUtils(context.getApplicationContext());
        }
        return mUtils;
    }

    private int getStatusBarHeight(){
        int resId = mContext.getResources().getIdentifier("status_bar_height","dimen","android");
        if(resId > 0){
            return mContext.getResources().getDimensionPixelSize(resId);
        }
        return 0;
    }

    /**
     *             
     */
    public float getXScal(){
        return mWidth / STANDARD_WIDTH;
    }

    /**
     *             
     */
    public float getYScal(){
        return mHeight / STANDARD_HEIGHT;
    }
}

次に、カスタムコントロール(RelativeLayoutやLinearLayoutなどを継承できる)を実装することにより、onMeasureで開発者が設定した画素値を取得し、数式で対応する割合を乗じて算出した実際の画素値をコントロールに設定して表示する
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    if (!flag) {
        float scalX = PixelUtils.getInstance(getContext()).getXScal();
        float scalY = PixelUtils.getInstance(getContext()).getYScal();
        int childCount = getChildCount();

        for (int index = 0; index < childCount; index++) {
            View child = getChildAt(index);

            LayoutParams layoutParams = (LayoutParams) child.getLayoutParams();
            layoutParams.width = (int) (layoutParams.width * scalX);
            layoutParams.height = (int) (layoutParams.height * scalY);

            layoutParams.leftMargin = (int) (layoutParams.leftMargin * scalX);
            layoutParams.rightMargin = (int) (layoutParams.rightMargin * scalX);
            layoutParams.topMargin = (int) (layoutParams.topMargin * scalY);
            layoutParams.bottomMargin = (int) (layoutParams.bottomMargin * scalY);

        }
        flag = true;
    }

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

上記のコードでは、flagの値を定義してタグ付けを行います.主にコントロールが二次ペイントを行う場合、最初のペイント時に設定した値に基づいて一次割合の計算を行います. = * * に相当します.したがって、計算結果の正確さのために、ここではflagの値を用いてタグ付けを行います.
最後に、自分のレイアウトでは自分のカスタムコントロールを使用できますが、ここで注意したいのは、ここでコントロールに設定した値は目標寸法に基づいた画素値であるべきなので、単位はpxであるべきです.

	

	

        
    


これで全体的にフィットが小さくなりますが、このシナリオは実際の運用では限界が大きく、小範囲での使用は問題ありませんが、プロジェクト全体で操作したい場合は、システムのDesityとDesityDpiを修正するシナリオを採用することをお勧めします.私のもう一つの記事Android画面の適合を実際に参考にすることができます.システムの画面画素比を変更することで、画面の適合効果を実現します.