这是在帮某厂商做DVB+IP的机顶盒中遇到的问题
界面中总共有四列(也就是四个ListView),需求要求对于选中的Listview中的Item有高亮的背景以及文本字体变成深蓝色,失去焦点但是被 选中的Item的文本的颜色显示深蓝色,其它时候显示白色
开发中遇到的问题有:
1:Item高亮的背景不对,有时候Item是被选中了但是就是没高亮,这种效果的做法有两种思路一是利用Listview的listSelector属性指定一个Selector的资源文件,另外一种是在Item的根View上指定一个Background属性为一个Selector的资源文件,由于此Item的文本中还有TextView的颜色变化 因此我采用了第二种做法,另外TextView的颜色变化一开始我也是按照网上说的给TextView的TextColor属性指定一个Selector的资源文件,但是貌似在Android5.0上这个属性是不支持的,因此最后将TextView的颜色的变化在根View的onFoucusChange()事件中实现了,可重点问题是高亮的背景依然是紊乱的,最后网上百度了很久才知道setItemsCanFocus(true)属性,这个属性设置以后Listview的Item才是能获取焦点的然后将Item的焦点传递到根View 于是背景高亮的问题才正常
2:Listview的Item失去焦点以后引起ListView的滚动,ListView的Item获取焦点的时候也引起了滚动,另外在Listview设置选中的焦点的Item的时候 Item会找错,也就是不是上次获取焦点的那个Item
Listview有 transcriptMode属性,将该属性设置为disable即可避免自动滚动,另外直接调用setSelection(int position)方法也会引起滚动,查了下源码这个方法内部调用的是setSelectionFromTop(int position,int top)而且第二个参数传递的是定值0,因此每次调用该方法时Item永远是滑动到可见视图的第一项,最后就直接调用setSelectionFromTop()方法并且将上次选中位置的top记录下来 下次获取焦点的时候传入该参数就解决了问题;然后需要说明一点的是getChildAt() 方法不能直接使用,特别是当Item很多时获取到的选中的Item往往不准确,因为Listview的Item会及时回收!需要减去getFirstVisiblePosition()这样获取的才准确
3:ListView 的Item中默认第一个的时候有一个选中的样式文本的也颜色是深蓝色,因此我是在Adapter的GetView()的方法中做的判断当position=0的时候给TextView添加的文本颜色,但是调试过程中发现 position=0的时候会执行多次,导致了默认的样式紊乱,后来在调试中发现刷新数据的时候调用NotifyDataSetChanged()方法后默认样式最容易紊乱,于是每次刷新数据我就new了一个Adapter,减少了紊乱的情况,但还是偶尔会出现紊乱的情况,网上百度了下解决方案 大部分说是在GetView()的方法中判断container.getChildCount()==position 的里面再去判断position 但是亲测还是无效,现在也无法解决这个问题,如果有网友知道怎么解决 还请留言我,非常感谢~~
4:最后一列节目列表的Listview时 要求里面的TextView有跑马灯的效果(只是选中的Item其它状态的不需要滚动),但是当Listview中Item的文本都超过文本长度时 跑马灯就失效了,而且也不能触发Click事件了,但是item有长文本和短文本一起时跑马灯是可以滚动的,网上百度了一些解决方案都说自定义一个TextView让getFocused()方法始终返回为true,再一个就是在Adapter的GetView()方法中判断当根View获取焦点时让TextView的SetSelection为true,其实我采用的是第二种方案,但还是出现了上面的问题(另外第一种是不满足需求的),这个问题现在也没有解决,如果网友知道解决方法,也可以留言我,非常感谢~~
另外一点需要说下,其实当时做这个界面的时候,也考虑过用RecycleView去替换ListView,但是需求中有个要求,需要每一列能翻页,当时使用RecycleView的时候就是这个翻页支持不太好,才使用了现在的Listview,ListView内置是支持翻页的,有兴趣可以翻下源码