ListView不使用adapter.notifyDataSetChange()修改item状态以及ListView.getChildAt()空指针异常解决方法

问题背景

在一个答题页面用ListView来展示4个选项,由于是单选,在点击是需要有一个点击的效果,其他选项则要恢复未选状态。一个解决思路是通过adapter.notifyDataSetChange()通知View重新绘制ListView的item,从而实现效果。但是这样做会有个问题就是每次重绘都会闪烁一次,并且如果已经滑动过的话会直接回到初始位置。导致体验很不好。

解决思路

通过ListView.getChildAt(int position)可以获取到指定position的itemView,首先遍历ListView的Child,然后findById()获取需要用到的View,进行初始化或者动画操作即可。

for(int i = 0;i < binding.listView.getCount();i++){
                            View item = binding.listView.getChildAt(i);
                            ChoiceView choiceView = (ChoiceView)item.findViewById(R.id.tv_choice);
                            if(i == position) {
                                choiceView.startAnim();
                            }else {
                                choiceView.initAnim();
                            }
                        }

这样处理貌似没有问题,但是当ListView的item项过多或这单个Item过大时,getChildAt()获取未展现出来的VIew时会报空指针异常。原因是getChildAt()只能获取到当前展示的item,一旦遍历到未展示的item就会报空指针异常。
空指针异常的解决方法是getChildCount(),ListView.getChildCount((ViewGroup.getChildCount) 返回的是显示层面上的“所包含的子 View 个数”。完整代码如下。

for(int i = 0;i < binding.listView.getChildCount();i++){
                            View item = binding.listView.getChildAt(i);
                            ChoiceView choiceView = (ChoiceView)item.findViewById(R.id.tv_choice);
                            if(i == position - binding.listView.getFirstVisiblePosition()) {
                                choiceView.startAnim();
                            }else {
                                choiceView.initAnim();
                            }

getFirstVisiblePosition()用于获取当前展示的第一个item的position,position - binding.listView.getFirstVisiblePosition()可以保证position必在childCount中。
问题解决!

猜你喜欢

转载自blog.csdn.net/q97531x/article/details/80857732