android-GridViewWithHeaderAndFooter icon indicating copy to clipboard operation
android-GridViewWithHeaderAndFooter copied to clipboard

bug: on TV, OnItemSelectedListener get the wrong position. FIXED.

Open com314159 opened this issue 9 years ago • 8 comments

I use this GridViewWithHeaderAndFooter view in a Android TV project, and in TV project. I found set OnItemSelectedListener not work properly.

com314159 avatar Mar 02 '15 08:03 com314159

我把这个控件放在电视盒子里使用, 添加了一个HeaderView, 发现用遥控器无法再控制GridView的焦点的移动了。 按遥控器的Down键无法从HeaderView跳到GridView的实际内容中。

com314159 avatar Mar 02 '15 08:03 com314159

这个是一个问题,有了HeaderView的,实际还有几个不可见的View在占位。

liaohuqiu avatar Mar 02 '15 09:03 liaohuqiu

en, 看懂了你的代码, 还在看怎么解决

com314159 avatar Mar 02 '15 10:03 com314159

想到解决方案了,一定push回来!静候佳音!

liaohuqiu avatar Mar 02 '15 13:03 liaohuqiu

我目前已经基本实现了, 下次找个时间有空, 我整理一下代码push过来, 但是不能保证实用性哦, 因为做TV版的毕竟少。 谢谢你的这个项目。

com314159 avatar Mar 03 '15 08:03 com314159

不好意思, 因为设计那边改了设计,暂时又去掉了GridView的头部。 因为我的实现还有一些bug, 我把实现的思想说一下吧, 如果有人遇到,可以参考一下。

原理 android TV遥控器上有4个按钮, 上下左右, 按任意一个按钮时, 移动对应的gridview的selectedItem, 如果需要滚动动,gridview会调用同时滚动, 同时gridview会调用OnItemSelectedListener 实现的代码在GridView.java的onKeyDown函数里面。

因为这个GridView的头部的实现,实际上和Listview的头部实现基本一样,只是,头部添加了占位的view。

所以, Gridview的selectedItem可能会到不可见的占位的view上面, 导致OnItemSelected取到的一些值是header或者footer的占位view

所以处理方法是: 当移动遥控器的SelectedPosition是占位的view时, 立即调用GridView的setSelection(int position)方法,让其选中一个非占位的view.

最关键的是, 实现过程容易出现很多bug, 需要考虑各种边界值。

最后,非常感谢作者!

com314159 avatar Mar 03 '15 13:03 com314159

呃,修改设计了……

liaohuqiu avatar Mar 04 '15 04:03 liaohuqiu

https://github.com/com314159/android-GridViewWithHeaderAndFooter

我已经上传代码到这个地址了, 可以实现OnItemSelectedListener的功能, 但是感觉实现有些怪。

在我们的项目上是没有体现出bug的, 在其他项目上可能会遇到bug

如果有人用到, 可以参考一下。

就是重写了setOnItemSelectedListener,使其跳过了无用的地方,但是返回的位置信息不好表达,所以新建了一个类RelativePosition来表达位置信息。

使用例子: mGridView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

        @Override
        public void onItemSelected(AdapterView<?> parent, View view,
                int position, long id) {
            KLog.i(TAG, " on grid view Item selected " + position);

            RelativePosition relativePosition = mGridView.getRelativePosition(position);

            if (relativePosition.mPositionType == RelativePosition.POSITION_ADAPTER) {
                mGridAdapter.setCurrentSeletedPos(relativePosition.mPosition);
            } else {
                mGridAdapter.setCurrentSeletedPos(-1);
            }

            mGridAdapter.notifyDataSetChanged();
        }

com314159 avatar Mar 05 '15 09:03 com314159