android屏幕适配的两种方式

适配中小型项目;

直接上代码,代码中有注释,考虑性能方面的原因,只适合中小型的项目,项目大了,会影响性能

  step1:

/**
 * 为了方便框架内部使用application 和得到context上下文 用
 */

public class MyApplication extends Application {

    private static MyApplication instance;
    public static MyApplication getInstance(){
        return instance;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        instance=this;
    }
}

strp2:

import android.content.Context;
import android.util.DisplayMetrics;
import android.view.WindowManager;

import java.lang.reflect.Field;

/**
 * 用来生成按美工的基准值生成真是设备需要的宽高值(1920*1080  720*480)
 */

public class UIUtils {

    //做成单列
    private static UIUtils ourInstance;
    public static UIUtils getInstance(){
        return  ourInstance;
    }
    public static UIUtils getInstance(Context context){
        if (ourInstance==null){
            ourInstance=new UIUtils(context);
        }
        return  ourInstance;
    }

    public static  final  float STANDARD_WIDHT=1080f;//标准值
    public static  final  float STANDARD_HEIGHT=1872f;//标准值1920-48(48px表示手机状态栏的高度)
    public static  final  String DIMEN_CLASS="com.android.internal.R$dimen";//拿到手机状态栏的高度

    //时间设备分辨率  480 800
    public float displayMetticsWidth;
    public float displayMetticsHeight;

    //初始化
    public  UIUtils(Context context){
        //获取屏幕的真实宽高
        WindowManager windowManager= (WindowManager) context.getSystemService(context.WINDOW_SERVICE);
        DisplayMetrics displayMetrics=new DisplayMetrics();
        if(displayMetticsWidth==0.0f || displayMetticsHeight==0.0f ){
            windowManager.getDefaultDisplay().getMetrics(displayMetrics);
            //获取状态栏的高度  48
            int sysytemBarHeight=getSysytemBarHeight(context);
            //处理真实宽高问题
            if(displayMetrics.widthPixels>displayMetrics.heightPixels){//宽度大于高度,横屏情况
                this.displayMetticsWidth=(float) displayMetrics.heightPixels;
                this.displayMetticsHeight=(float) displayMetrics.widthPixels-sysytemBarHeight;
            }else {//竖屏
                this.displayMetticsWidth=(float) displayMetrics.widthPixels;
                this.displayMetticsHeight=(float) displayMetrics.heightPixels-sysytemBarHeight;
            }

        }
    }

    /**
     * 获取状态栏高度
     * @param context
     * @return
     */
    private int getSysytemBarHeight(Context context) {
        return getValue(context,"com.android.internal.R$dimen","system_bar_height",48);
    }

    /**
     * 获取像素
     * @param context 上文
     * @param attrGroupClass  android源码中存放维度的类
     * @param attrName  状态栏的信息
     * @param deFault   缺省默认值
     * @return
     */
    private int getValue(Context context, String attrGroupClass, String attrName, int deFault) {
        try {
            Class e=Class.forName(attrGroupClass);
            Object obj=e.newInstance();
            Field field =e.getField(attrName);
            //获取到的是一个id
            int x=Integer.parseInt(field.get(obj).toString());
            //把id转化成像素返回出去
            return context.getResources().getDimensionPixelOffset(x);
        } catch (Exception e1) {
           // e1.printStackTrace();
            return deFault;
        }
    }


    //开始获取缩放以后的结果
    public float getWidth(float width){
        return width*this.displayMetticsWidth/STANDARD_WIDHT;
    }

    //开始获取缩放以后的结果
    public float getHeight(float height){
        return height*this.displayMetticsHeight/STANDARD_HEIGHT;
    }

    //开始获取缩放以后的结果
    public int getWidth(int width){
        return (int)(width*this.displayMetticsWidth/STANDARD_WIDHT);
    }

    //开始获取缩放以后的结果
    public int getHeight(int height){
        return (int)(height*this.displayMetticsHeight/STANDARD_HEIGHT);
    }


}

step3:

import android.view.View;
import android.widget.LinearLayout;

/**
 *  view的计算工具
 */

public class ViewCalculateUtil {

    //获取调用层传入的值进行设置
    public static void setViewLinearLayoutParam(View view, int width,int height,int topMargin, int bottomMargin,int leftMargin,int rightMargin){
        LinearLayout.LayoutParams layoutParams= (LinearLayout.LayoutParams) view.getLayoutParams();
        if(width !=LinearLayout.LayoutParams.MATCH_PARENT && width !=LinearLayout.LayoutParams.WRAP_CONTENT){
            //用自己的My 需要在manifests 中添加  android:name=".MyApplication"
            layoutParams.width=UIUtils.getInstance(MyApplication.getInstance()).getWidth(width);
        }else{
            layoutParams.width=width;
        }
        if(height !=LinearLayout.LayoutParams.MATCH_PARENT && height !=LinearLayout.LayoutParams.WRAP_CONTENT){
            //用自己的My 需要在manifests 中添加  android:name=".MyApplication"
            layoutParams.height=UIUtils.getInstance(MyApplication.getInstance()).getHeight(height);
        }else{
            layoutParams.height=height;
        }
        // height 是竖着缩放
        // weight  横着缩放
        layoutParams.topMargin=UIUtils.getInstance(MyApplication.getInstance()).getHeight(topMargin);
        layoutParams.bottomMargin=UIUtils.getInstance(MyApplication.getInstance()).getHeight(bottomMargin);
       //横向上百分比计算
        layoutParams.leftMargin=UIUtils.getInstance(MyApplication.getInstance()).getWidth(leftMargin);
        layoutParams.rightMargin=UIUtils.getInstance(MyApplication.getInstance()).getWidth(rightMargin);
        view.setLayoutParams(layoutParams);
    }

}

在activity如何使用:

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private TextView text1;
    private TextView text2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        text1 = (TextView) findViewById(R.id.text1);
        text2 = (TextView) findViewById(R.id.text2);
        ViewCalculateUtil.setViewLinearLayoutParam(text1,1040,80,10,0,20,20);
        ViewCalculateUtil.setViewLinearLayoutParam(text2,400,400,50,0,0,0);
    }
}


运行结果:







第二种方式:

适合中大型项目的方式,性能比较优异

step1:

value里面的代码:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="PercentRelativeLayout">
        <!--宽度的百分比-->
        <attr name="layout_widthPrecent" format="float"></attr>
        <attr name="layout_heightPrecent" format="float"></attr>
    </declare-styleable>
    
</resources>

自定义百分比布局:

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;

/**
 * 自定义百分比 RelativeLayout
 */

public class PrecentRelativeLayout extends RelativeLayout{

    public PrecentRelativeLayout(Context context) {
        super(context);
    }

    public PrecentRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public PrecentRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width= ViewGroup.MeasureSpec.getSize(widthMeasureSpec);
        int height= ViewGroup.MeasureSpec.getSize(heightMeasureSpec);
        //测量出子控件的宽高进行改变
        int childCount=this.getChildCount();
        for(int i=0;i<childCount;i++){
            View child=this.getChildAt(i);
            ViewGroup.LayoutParams layoutParams=child.getLayoutParams();
            //把已经得到的布局参数进行更改
            float widthPrecent=0;
            float heightPrecent=0;
            if(layoutParams instanceof  PrecentRelativeLayout.LayoutParams){
                //获取到布局文件上的内容
                widthPrecent = ((LayoutParams) layoutParams).getWidthPrecent();
                heightPrecent = ((LayoutParams) layoutParams).getHeightPrecent();
            }
            if(widthPrecent>0){
                layoutParams.width=(int)( width * widthPrecent);
                layoutParams.height=(int)( height * heightPrecent);
            }
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
    }

    //通过需要把自定义属性封装进去
    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        //返回自己设置好的布局参数
        return new LayoutParams(getContext(),attrs);
    }


    public  static  class  LayoutParams extends RelativeLayout.LayoutParams{
        private float widthPrecent;
        private  float heightPrecent;

        public float getWidthPrecent() {
            return widthPrecent;
        }

        public void setWidthPrecent(float widthPrecent) {
            this.widthPrecent = widthPrecent;
        }

        public float getHeightPrecent() {
            return heightPrecent;
        }

        public void setHeightPrecent(float heightPrecent) {
            this.heightPrecent = heightPrecent;
        }

        /**
         * 把自定义属性加入
         * @param c
         * @param attrs
         */
        public LayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);
            TypedArray typedArray=c.obtainStyledAttributes(attrs,R.styleable.PercentRelativeLayout);
            widthPrecent=typedArray.getFloat(R.styleable.PercentRelativeLayout_layout_widthPrecent,this.getWidthPrecent());
            heightPrecent=typedArray.getFloat(R.styleable.PercentRelativeLayout_layout_heightPrecent,this.getHeightPrecent());
        }

        public LayoutParams(int w, int h) {
            super(w, h);
        }

        public LayoutParams(ViewGroup.LayoutParams source) {
            super(source);
        }

        public LayoutParams(MarginLayoutParams source) {
            super(source);
        }

        public LayoutParams(RelativeLayout.LayoutParams source) {
            super(source);
        }
    }
    
}


step2:

如何使用呢,在layout布局文件中做如下代码操作,把根据点替换

<?xml version="1.0" encoding="utf-8"?>
<com.sj.screenadapter02.PercentRelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.sj.screenadapter02.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_widthPrecent="0.5"
        app:layout_heightPrecent="0.5" />

</com.sj.screenadapter02.PercentRelativeLayout>

activity里面不改变,

运行结果如下:





第三种:这两种结合起来,可以做成一个万能适配方案,可以自己尝试一下,思想就是这样。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值