FastScroller仅滚动回第一个元素,而不是标题视图

Mic*_*der 19 android listview android-listview

我已经在ListView中启用了快速滚动,它具有不可选择的标题视图.如果向下滚动列表并将快速滚动滑块拖动到顶部,则列表仅向后滚动到第一个元素,而不是向标题视图滚动.拖动列表,按预期工作.

屏幕截图1:屏幕截图中的红色区域是标题视图.
屏幕截图2:如果您将拇指拖到顶部,则只能获得第一个元素,标题视图仍然位于上方.

ListView lv = (ListView) findViewById(R.id.listView);
lv.addHeaderView(getLayoutInflater().inflate(R.layout.view,null), null, false);
Run Code Online (Sandbox Code Playgroud)

 

<ListView 
   android:layout_height="fill_parent" 
   android:id="@+id/listView" 
   android:layout_width="fill_parent"
   android:fastScrollEnabled="true"
></ListView>
Run Code Online (Sandbox Code Playgroud)

我创建了一个演示项目:https: //github.com/mikegr/fastscroll-bug

为什么拖动拇指不会滚动回到顶部?

红色区域是标题视图 拖动拇指不会回到顶部

add*_*aon 12

这是故意的行为FastScroller.当你打电话setAdapter给你时ListView,HeaderViewListAdapter如果有任何标题设置,适配器将被包装; 这就是你addHeaderView之前必须打电话的原因setAdapter.然后,在FastScroller代码中,我们看到:

    if (adapter instanceof HeaderViewListAdapter) {
        mListOffset = ((HeaderViewListAdapter)adapter).getHeadersCount();
        adapter = ((HeaderViewListAdapter)adapter).getWrappedAdapter();
    }
Run Code Online (Sandbox Code Playgroud)

也就是说,获取偏移并使用底层适配器.mListOffset然后用于设置顶部位置以使用快速滚动条滚动到.那么这种包装究竟会在哪里发生?正如预期的那样,ListView.addHeaderView我们看到的地方:

    if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
        mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
    } else {
        mAdapter = adapter;
    }
Run Code Online (Sandbox Code Playgroud)

所以我们肯定在寻找合适的地方.现在,听起来你的目标是没有快速拇指的列表标题的偏移行为,但是否则有一个带标题的普通列表.要做到这一点,就足够了(基于我们已经看到过的代码)FastScroller.mListOffset = 0.这仅在getSectionsFromIndexer无条件调用时设置init,并且仅在其他几个函数中有条件地设置mListAdapter == null.mListAdapter如果onSectionsChanged被调用则仅为null ,所以让我们暂时忽略该路径.

经过大量的挖掘,并使用各种反射钩,我可以说,没有办法做到这一点,即使是稍微未来兼容.您可以使用反射来替换HeaderViewListAdapter,以获取与其标题计数等相关的内容; 但那很脆弱.类似地,您可以将(包可见)FastScroller子类化为具有您自己行为的一个; 但是mListOffset被广泛引用而不是通过吸气剂,所以这甚至比平常更加丑陋.基本上,你正在遇到系统无法按照你想要的方式运行的事实.

我毫不犹豫地称这是一个错误,因为从代码中可以清楚地看出它是故意的行为.您是否考虑过将列表的第一个元素作为一个特殊的第一个元素(可能使用自定义WrapperListAdapter,HeaderViewListAdapter如果需要更好地保存),而不是使用标题机制?