适配中小型项目;
直接上代码,代码中有注释,考虑性能方面的原因,只适合中小型的项目,项目大了,会影响性能
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"?>name="PercentRelativeLayout"> name="layout_widthPrecent" format="float"> name="layout_heightPrecent" format="float">
自定义百分比布局:
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;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"?>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"> android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_widthPrecent="0.5" app:layout_heightPrecent="0.5" />
activity里面不改变,
运行结果如下:
第三种:这两种结合起来,可以做成一个万能适配方案,可以自己尝试一下,思想就是这样。