android自定义控件无法显示的原因

时间:2022-10-07 18:55:14


android自定义控件无法显示的原因

​编者:李国帅​

时间:2020/8/1 

背景:

Android开发中经常会遇到时间选择,而且经常会被要求使用类似ios的滚轮风格。只是android并不是ios,没有滚轮的时间选择器,那就需要进行定制,网上也有不少的开源定制View。一次,我在使用的时候,不知道改动了哪个地方,控件怎么也显示不出。

前后比较:

原本应该是这样的:

android自定义控件无法显示的原因

 

可是被改动之后,怎么也显示不出来

 

android自定义控件无法显示的原因

解决过程:

怎么回事呢?原来是好的,后来不行了,自己到底改动了什么?我的注意力被吸引在对比上,反反复复的比较原代码和新代码的差异,总是不觉得自己改了什么。

而且还有个问题,虽然不能显示控件,但是从logcat和console不能找到任何异常或错误日志,编译器也没有提示。

反复检测比较几次后搞得自己没脾气,这部分代码还是挺多的,难道自己有必要走读代码吗?

最后静下心,才发现,自己对出现的问题还是太急躁了,问题还是要从源头去分析。

问题的本质是控件的大小和可见性,时间段View的核心是WheelView,而WheelView被类WheelTime管理,WheelView中的数字TextView的字体大小在WheelView构造函数中定义,该字体大小又在TimePickerView构造函数中定义,继续向上追溯是由setContentSize函数定义。

错误的根源在于这么一句.setContentSize(px2sp(context, R.dimen.sp_17)),其中错误的使用了函数px2sp。

    public static int px2sp(Context context, float pxValue) {

        final float scale = context.getResources().getDisplayMetrics().scaledDensity;

        return (int) (pxValue / scale + 0.5f);

    }

而正确的函数应该是

   public static int px2sp(Context context, int id) {

        float pxValue = context.getResources().getDimension(id);

        final float scale = context.getResources().getDisplayMetrics().density;

        return (int) (pxValue / scale + 0.5f);

}

在java中这种隐式的类型转换很难被发现,而且即便是真的有隐患,使用try…catch,只要不打印出来,依然难以从logcat或console找到线索。

 

         这也是自己比较代码的时候,习惯性认为某些惯用函数是正确的,而忽视了某些非常见用法。而程序作为一个整体,单个函数的正确并不代表程序功能的正确。

总结:

解决后发现这个问题的本质并不复杂,但是花费了很长时间。

产生原因还是因为修改和移植没有注意细节。

解决时间过长是因为自己心中的执念。老是纠结于为什么原来可以现在怎么就不可以,而不是静下心来,聚焦于问题的源头,抓住问题的关键和本质。

 

我想,人生中还是有许多问题,并不是不能解决,而是自己愿不愿意下决心去解决。

与其纠结于那么多为什么,而不静下心一步步分析,一步步接近问题的真相,和我们期望的结果。