Android笔记之快速简单的适配

来源:互联网 发布:今日网络热点 编辑:程序博客网 时间:2024/05/12 08:42

大家都知道,做android开发适配屏幕是回避不了的问题,大量的xml布局、values文件、不同分辨率的图片让我们头疼,我们也一直在思考有没有一种方法直接改变缩放比例可以一次完成适配。那么,我们开始试试吧。
通过一个函数,改变应用对res下资源解析时对宽高的计算:

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)    public static void initDpi(Context context) {        DisplayMetrics dm = new DisplayMetrics();        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {            wm.getDefaultDisplay().getRealMetrics(dm);        } else {            try {                Class<?> c = Class.forName("android.view.Display");                Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);                method.invoke(wm.getDefaultDisplay(), dm);            } catch (Exception e) {                e.printStackTrace();            }        }//        DisplayMetrics dm = context.getResources().getDisplayMetrics();        float sw = Math.min(dm.widthPixels, dm.heightPixels);        float xsw = sw / dm.density;        float r = xsw / 800f;        Configuration configuration = context.getResources().getConfiguration();        // densityDpi值越大,显示时dp对应的pix就越大        configuration.densityDpi = (int) (dm.densityDpi * r);         context.getResources().updateConfiguration(configuration, null);    }

以上代码最关键的部分在于最后updateConfiguration方法的调用,阅读源码我们知道每一个activity都具有一个Context对象,每个Context对象都具有一个Resources对象,恰好该Resources对象又具有一个Configuration对象。Configuration对象对象中存储了大量跟系统以及设备相关的参数,比如屏幕宽高、分辨率、缩放、dpi等。通过updateConfiguration方法我们可以变更相关参数,以上代码通过计算赋值改变了densityDpi参数。我们res目录下的资源在解析的时候,都会通过Configuration对象的densityDpi进行从dp到px的计算。以上代码在计算densityDpi的时候以800f为参考比例,这是因为项目中UI人员在切图和间隔标注时是按照800*1280做的,这个地方要根据实际需要做出变更。

由于有时候需要对整个应用做出对应更改,我们可以通过在Application的继承类(记得在manifest中声明)的onCreate方法中添加

        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {            @Override            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {                initDpi(activity.getBaseContext());            }            @Override            public void onActivityDestroyed(Activity activity) {            }            @Override            public void onActivityPaused(Activity activity) {            }            @Override            public void onActivityResumed(Activity activity) {            }            @Override            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {            }            @Override            public void onActivityStarted(Activity activity) {            }            @Override            public void onActivityStopped(Activity activity) {            }        });

当然,这个方法只能解决同方向的适配,横竖屏还是老实的做两套方案吧。

原创粉丝点击