ListView 中 getSelectedView() 和 getSelectedItem() 区别
来源:互联网 发布:淘宝试用官网 编辑:程序博客网 时间:2024/06/11 18:09
本文是基于作者遇到的一个bug而来,如果正常情况下,可以不考虑本文做法。
从官方的注释上看getSelectedView()
好像是得到当前选中的 item 的view
,getSelectedItem()
得到的当前选中的 item 所绑定的数据。这两个得到的数据类型都不相同怎么比较?
首先,看到getSelectedItem()
的源码 实现:
/** * @return The data corresponding to the currently selected item, or * null if there is nothing selected. */ public Object getSelectedItem() { T adapter = getAdapter(); int selection = getSelectedItemPosition(); if (adapter != null && adapter.getCount() > 0 && selection >= 0) { return adapter.getItem(selection); } else { return null; } }
可以看到 return 的是adapter.getItem(selection)
,也就是我们要重写的 Adapter 里面的getItem()
函数。如果重写的时候我们返回的不是data
数据,而是当前选中的itemView
(自定义的view)的话,就可以与getSelectedView()
相比较了(在重写getView()
里面,已经把自定义的itemView
设置为了convertView
的tag
了,也就是(getSelectedView().getTag() instanceof itemView)
)。
再接着看int selection = getSelectedItemPosition();
,点击看到getSelectedItemPosition()
的源码:
public int getSelectedItemPosition() { return mNextSelectedPosition; }
返回的是mNextSelectedPosition
!下一个位置!
再看到getSelectedView()
的源码
public View getSelectedView() { if (mItemCount > 0 && mSelectedPosition >= 0) { return getChildAt(mSelectedPosition - mFirstPosition); } else { return null; } }
由于一般mFirstPosition
的值为0,所以也可以看作是返回getChildAt(mSelectedPosition)
当前选中的位置!
根据源码可以看出这两个方法得到的数据是有一点区别的,可是我们平时用的时候好像完全感觉不到,直到遇到特定的情况的时候,也就是我遇到的bug。
项目有个需求,是在右边的Fragment
切换时,左边的菜单ListView
会刷新选中项,并且选中项改变时,做一些效果(选中和失去)。我给ListView
注册了一个监听器OnFocusChangeListener
,代码如下:
OnFocusChangeListener onFocusChangeListner = new OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { Log.d(TAG, "hasFocus = " + hasFocus + ", pos = " + menuListView.getSelectedItemPosition()); Log.d(TAG, "getSelectedView = " + menuListView.getSelectedView().getTag()); Log.d(TAG, "getSelectedItem = " + menuListView.getSelectedItem()); if (hasFocus) { //给菜单ListView选中项设置为“第一焦点” setFirstFocus(); } else { //给菜单ListView选中项设置为“第二焦点” setSecondFocus(); } }};menuListView.setOnFocusChangeListener(onFocusChangeListner);
为什么要这样做,就是因为menuListView
有两种状态的焦点,一种是选中时并且也得到焦点时(称为“第一焦点”),另一种是选中时但是焦点不在上面(称为“第二焦点”)。
第一焦点 第二焦点
接下来执行操作,当选中项为“媒体”且焦点不在ListView
上时,切换右侧Fragment
到“应用”,这个时候理想状况是“第二焦点”状态转移到“应用”。
我的做法是:在setFirstFocus()
中得到当前选中menuListView.getSelectedView().getTag()
设置为第一焦点文字颜色;在setSecondFocus()
中得到当前选中menuListView.getSelectedView().getTag()
设置为第二焦点文字颜色。(这里不考虑红色块背景以及右侧红色条,因为不属于ListView里面的部分,为了有滑动动画,是用ImageView
另外做的)。
当两个方法使用的都是getSelectedView()
时,效果变成了这个样子:
看打印发现onFocusChange
调用了两次,第一次打印hasFocus = true, pos = 2
;第二次打印hasFocus = false, pos = 2
。
而getSelectedView().getTag()
得到的itemView
是pos = 1
的view
,getSelectedItem()
得到的itemView
是pos = 2
的view
。(怎么知道的?通过打印getView()
里面所有position
的itemView
对比 id 号得出)
如前言所述,getSelectedItem()
得到的是getSelectedView()
的下一项!
可以根据现象证明,两次调用第一次把“媒体”设置为了第一焦点,第二次把“媒体”设置为了第二焦点。这显然不是我想要的结果。根据“应用”选项放大也可以看出现在选中项是“应用”。
如果这样调整:在setFirstFocus()
和setSecondFocus()
中把menuListView.getSelectedView().getTag()
替换为menuListView.getSelectedItem()
。
效果变成了:
很明显,应该改成setFirstFocus()
里面调用menuListView.getSelectedView().getTag()
,setSecondFocus()
里面调用menuListView.getSelectedItem()
。
完整效果图示:
1.作为第一焦点时
2.按右,作为第二焦点时
3.按下,第二焦点切换
/** * ━━━━━━神兽出没━━━━━━ * ┏┓ ┏┓ * ┏┛┻━━━┛┻┓ * ┃ ┃ * ┃ ━ ┃ * ┃ ┳┛ ┗┳ ┃ * ┃ ┃ * ┃ ┻ ┃ * ┗━┓ ┏━┛ 看不懂,没关系.. * ┃ ┃ * ┃ ┗━━━┓ * ┃ ┣┓ * ┃ ┏┛ * ┗┓┓┏━┳┓┏┛ * ┃┫┫ ┃┫┫ * ┗┻┛ ┗┻┛ * * ━━━━━━神兽保佑,代码无bug━━━━━━ */
- ListView 中 getSelectedView() 和 getSelectedItem() 区别
- MFC CTreeView学习之右键菜单_获取选中节点的方式HitTest和GetSelectedItem的区别(二)
- android 中listView 和GridView 区别
- ListView中convertview和ViewHolder的区别
- Android中ListView.getCount()与ListView.getChildCount()区别和OnScrollListener()各个参数的区别
- Android中ListView.getCount()与ListView.getChildCount()区别和OnScrollListener()各个参数的区别
- Android中ListView.getCount()与ListView.getChildCount()区别和OnScrollListener()各个参数的区别
- Android中ListView.getCount()与ListView.getChildCount()区别和OnScrollListener()各个参数的区别
- Android中ListView.getCount()与ListView.getChildCount()区别和OnScrollListener()各个参数的区别
- Android中ListView.getCount()与ListView.getChildCount()区别和OnScrollListener()各个参数的区别
- RecyclerView 和 ListView 区别
- 浅谈ListView自带的滚动条和ScrollView中嵌套ListView的区别
- scrollview和listview的区别
- ListView 和 GridView的区别
- RecyclerView 和 ListView的区别
- RecyclerView和listview的区别
- RecyclerView 和 ListView 的区别和联系
- RecyclerView 和 ListView 性能和效果区别
- linux信号处理函数
- MFC控件数据交换:DDX
- ssh tunnel 代理
- 动态代理可以使代理模式更加灵活
- 工厂方法PK抽象工厂
- ListView 中 getSelectedView() 和 getSelectedItem() 区别
- 如何自定义FragmentTabHost中某一个Tab的点击效果
- opencv学习篇(8)轮廓的查找、表达、绘制、特性及匹配
- 技术向:一文读懂卷积神经网络
- ——黑马程序员——OC中的多态
- 一个计算元素到窗口的边距的函数
- jQuery:12 个非常实用的 jQuery 代码片段
- leetcode-Pascal's Triangle
- 如何使用ChartControls