今天解决了一个问题,
1. listview切换横屏之后,item左边距不对导致界面被打孔屏截断
2. 横屏下切换多屏模式之后切换回竖屏,item左边距太大
全部代码在最下边
以我丰富的界面适配的经验来看(哈哈哈),呵,很简单呀,没监听到横竖屏变化还有切换多屏模式的监听呀,so easy。于是查看代码,发现是被其他同事将adapter中getview的时候进行的边距适配逻辑改了,将之前的每一个getview的时候都进行边距适配移到了viewholder实例化的地方去了,于是沟通了一下,得到了如下的结论:
1. 这个边距计算很耗时,占用了基本上getview的一半时间,使界面滑动的性能不达标
2. 如果只在viewholder实例化的地方调用,很明显,当横竖屏切换的时候因为activity已经设置了不在横竖屏切换的时候重新构建,导致viewHolder也实现了复用,于是这些带着竖屏的边距的view就被viewHolder带入到了横屏,导致出现了问题。
这样看来,首先确认一点,我直接拿出来的方法是不可能了,如果我直接拿出来,性能优化又得放进去,界面适配又得拿出来,这样我这下半辈子可能都得改这一个bug了。
在经历了好多的方法测试之后得到了一个最佳的解决方案。
先把测试的方案列出来,然后把却缺点记录一下:
1、 只有第一次viewHolder构建的时候才会进行边距适配,并且因为涉及到的是横竖屏切换还有多屏模式的切换,那我是否可以直接在横竖屏等切换中通过变量控制adapter,在getview的时候通过变量控制,如果经历过横竖屏切换,那我就把getview的convertView清空不就得了嘛,再让他重新创建一次。结果失败了,横竖屏切换之后只有第一个item是对的,其他的还是保持和原来一样,这里面就引发了我的第一个疑问。
2、于是乎第二个方案:其实item的边距都是一样的呀,那我为什么不用一个直接写在布局里面的view来实现边距呢,然后在初始化viewholder的时候直接把这个边距设给这个viewholder,然后借助第一个方案不就行了嘛,看起来问题已经解决了呀,然后,viewholder创建布局,初始化。。。结果又TM失败了,怎么回事儿,又是只有第一个对了,其他的又阵亡了,看来viewholder还是没有给所有的view设置上
3.不信了,第三个方案,我用变量控制边距适配的执行,横竖屏切换我就调用,这样应该可以了吧,然后执行之后再把变量设置回来,但是想了一下不行,getview会走多次呀,这样又是第一个view对了。其他的还是不行,但是我要保证变量不设置回来,那性能问题又回来了,于是方案三夭折在娘胎了
4. 方案四,我通过屏幕的方向设置呢?哎,好像是可以呀,我在每一个viewholder中添加一个方向,在adapter中保存一个界面的整体方向,什么时候切换方向了我再改变这个值,然后再执行边距适配。经过一顿猛如虎的编码,编译,测试,横竖屏切换,哎可以了呀,再切换,哎可以了呀,再来,又可以了,看来我已经解决了,那来个多屏试试,哎也行,来多屏旋转屏幕,卧槽,边距呢,怎么又不对了。。此刻的我崩溃了,下楼抽了一根难受的香烟。就在抽烟的时候灵感突现,没添加分屏的监听呀,好起来了,于是上楼,在分屏变换回调中添加设置变量,再测试,多屏切横屏走起,还是不行,发现我在竖屏的时候进入分屏居然把屏幕的方向变成了2(横屏的参数),神奇呀,老弟,跟我开玩笑呢嘛,时间紧,没时间找系统的人帮忙看一下到底是什么情况了,于是接着想方案5
5、 绕开方向,我直接使用boolean变量控制,你转屏幕我就取反,你进多屏我就取反,此处省略编码,编译,调试走起!好像可以了呀,切了十次,都没事儿了,好找测试验证一下,人多力量大,5分钟之后大哥告诉我不行,我满脑子问号,还他么不行,但是还得开开心心的过去,看一眼,发现这大哥先切了横屏,然后竖屏,然后再横屏,90 270度一顿操作,,然后把listview往上滑,我草,上边的item这帮兄弟是怎么了,你怎么没跟下边的一起动起来呀,终于复现了,我想着大哥,我把问题改成概率的了,我没测出来你测出来了,还得是专业人士呀,于是想了一下,切换的过程中没有在界面中展示的item连续触发了两次就gg了,恩,取反再取反不就回来了嘛,方案五也pass了,
6、 老板,我想换个单子,不接了,我改成概率的了,用户测不出来的,当然这些都是内心的想法,于是神圣而又伟大的方案6诞生了,我取反取反取反,这样不行,那我+1,+1,+1呢,还是原套路,viewholder存一个int型的变量,记录一下之前触发边距适配逻辑时候的tag,然后这次我转一次,我就+1,我进多屏我还+1,但是想了一想,我要+超了怎么办,恩,不能,从用户的角度考虑list他转个100次就够够的了,从稳定性的角度考虑,int型这么大,你能给我跑超界了?于是同样的套路,不一样类型的变量,调试,足足5分钟,终于啥问题没有了,找测试大大,大哥在那转了10分钟也没事儿,好了,提代码,走单咯,
疑问1:viewHolder是每一个item一个嘛?我怎么不记得这个知识呢,
疑问2:viewholder到底什么时候初始化,只有当第一个加载过后的item滚出屏幕之后嘛
疑问3:viewholder到底是怎么复用的,几个item复用一个viewholder,界面能装4个item,那第一个和第五个的viewholder是不是一个
疑问4:竖屏下进入多屏为什么orientation会变成横屏的2
由于不能公司保密协议,不能贴代码,只能靠想象了,哈哈哈,彩蛋哟,不过还是可以大家讨论一下相关的原理的
为了不让自己忘记这个问题,(说明这个bug对我造成了多么大的影响),为了记录一下,方便哪天有时间自己好好看一下viewholder,为了祖国的繁荣,于是写下了这个不算总结的总结,如果有大佬之后我的疑问,可以帮我解答,要钱没有,以武会友,也希望大家共同去讨论这几个问题。祝大家工作顺利,bug全解
一杯茶,一包烟,一个bug解一天