先说问题,最近有一个小需求是对一个对话框的标题超过两行打点显示,如下图所示。在没有修改之前这个对话框是超过一行打点。
这本来是一个非常简单的需求,原来是一行打点,实现是这样。
android:ellipsize="end"
android:maxLines="1"
我只需要将maxLines="1"中的1改成2即可。
android:ellipsize="end"
android:maxLines="2"
如果问题就这样解决了,也就没必要写这篇文章了。
诡异的现象
程序运行后发现,代码并没有生效,对话框还是一行打点。最开始以为是Android studio的问题,于是重启重新编译运行,发现还是没有生效。然后我试了另外两种方式居然生效了。
一种方式是在代码中设置最大行数。
TextView mTvTitle = (TextView) layout.findViewById(R.id.tv_title);
mTvTitle.setMaxLines(2);
另一种方式是重新建一个工程,将相关的代码原封不动的拷贝过去。
这个现象非常奇怪,有两个问题需要思考:
1、为什么相同的代码在不同的工程里却有不同的结果。
2、为什么在布局文件里,代码没有生效,而在代码中设置就生效了。
于是我带着这两个问题思考下去。
先看第一个问题:
为什么相同的代码在不同的工程里却有不同的结果。
第一个工程是一个很庞大的工程,另一个是新建的工程。虽然他们的对话框的代码是一样的,但是他们的环境是不一样的。我最开始想到是不是他们的SDK的版本,主题,项目依赖的库不同造成的。做了一些对比试验后这些猜测都被否决了,TextView 是android.widget包下的类,也不太可能受其他库的影响。因为两个工程不相同的东西太多,也没办法一一做对比试验,只好放弃。
第一个问题无果,再看第二个问题:
为什么在布局文件里,代码没有生效,而在代码中设置就生效了。
最开始我以为是不是ellipsize和maxLines一起使用冲突的问题,因为之前发现过在TextView 中同时使用 ellipsize=start/middle/marquee/none (ellipsize=end不会报错)和 maxLines属性可能导致运行时崩溃。根据Google Issue 上的报告,这个 bug 从 Android 4.1 到 7.0 都有人报告。
对应的issue: https://issuetracker.google.com/issues/36950033
不过很快这个想法也被否决了,因为在我修改之前ellipsize=end与maxLines=1是结合使用的,并且也出现了一行打点的效果。
柳暗花明
思考了一圈没有找到问题的原因,不过可以肯定的是ellipsize=end与maxLines结合使用是没有问题的,问题的关键是我修改了布局文件却没有生效。那么就只剩下一种可能,这个布局文件没有被使用,还有另一个相同的布局文件存在,想到这的时候,细思极恐,仿佛找到了真正的杀人凶手一般,而这个杀手一直隐藏在你的身后。
按照这个思路我去全局搜索了一下这个布局文件,结果和预期的一样,真的有两个相同命名的文件。
一个在主工程一个在中间层的module中。
结果已经很清晰了,原来是其他同事在做组件化的过程中,将一些公共组件移到另外的module时是通过复制粘贴的方式,而这样的方式很容易导致主工程的一些文件忘记删除。而程序在找布局文件时会优先从主工程开始找,所以便出现了我们在中间层的module中修改代码却没有生效的情况。上文中出现的两个诡异现象也就很好解释了。