【问题标题】:FastScroller only scrolls back to the first element, not to the header viewFastScroller 只滚动回第一个元素,而不是标题视图
【发布时间】:2011-10-24 12:51:22
【问题描述】:

我在 ListView 中启用了快速滚动,它有一个不可选择的 headerview。如果您向下滚动列表并将快速滚动拇指拖到顶部,则列表只会滚动回第一个元素,但不会滚动到标题视图。拖动列表,按预期工作。

屏幕截图1:屏幕截图中的红色区域是标题视图。
屏幕截图2:如果您将拇指拖到顶部,您只会到达第一个元素,并且标题视图仍在上方。

ListView lv = (ListView) findViewById(R.id.listView);
lv.addHeaderView(getLayoutInflater().inflate(R.layout.view,null), null, false);

 

<ListView 
   android:layout_height="fill_parent" 
   android:id="@+id/listView" 
   android:layout_width="fill_parent"
   android:fastScrollEnabled="true"
></ListView>

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

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

【问题讨论】:

  • 你有没有发现如何解决这个问题?

标签: android listview android-listview


【解决方案1】:

这是FastScroller 的故意行为。当您在ListView 上调用setAdapter 时,如果设置了任何标头,则适配器将包装在HeaderViewListAdapter 中;这就是为什么你必须在setAdapter 之前调用addHeaderView。然后,在FastScroller 代码中,我们看到:

    if (adapter instanceof HeaderViewListAdapter) {
        mListOffset = ((HeaderViewListAdapter)adapter).getHeadersCount();
        adapter = ((HeaderViewListAdapter)adapter).getWrappedAdapter();
    }

即获取偏移量并使用底层适配器。 mListOffset 然后用于设置使用快速滚动条滚动到的顶部位置。那么这种包装实际上发生在哪里呢?正如预期的那样,直到ListView.addHeaderView,我们看到:

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

所以我们肯定在寻找正确的地方。现在,听起来您的目标是不让您的快速拇指的列表标题具有偏移行为,而是有一个带有标题的普通列表。为此,拥有FastScroller.mListOffset = 0 就足够了(基于我们对代码的了解)。这仅在getSectionsFromIndexer 中设置,在init 中无条件调用,仅在mListAdapter == null 时在其他几个函数中有条件调用。 mListAdapter 只有在 onSectionsChanged 被调用时才为空,所以我们暂时忽略该路径。

经过大量挖掘,并使用各种反射钩子,我可以说没有办法做到这一点,甚至有点未来兼容。您可以使用反射将 HeaderViewListAdapter 换成一个关于其标题计数等的;但这很脆弱。类似地,您可以将(包可见)FastScroller 子类化为具有您自己行为的一个;但是mListOffset 被广泛引用,而不是通过吸气剂,所以这比平时更丑陋。基本上,您会遇到这样一个事实,即系统不能完全按照您想要的方式工作。

我不愿将此称为错误,因为从代码中可以清楚地看出这是故意的行为。您是否考虑过让列表的第一个元素只是一个特殊的第一个元素(如果需要记账,可能使用自定义的WrapperListAdapter,就像HeaderViewListAdapter),而不是使用标题机制?

【讨论】:

  • 较新的“mListOffset”现在称为“mHeaderCount”。我将两者都设置为 0,一切似乎都很好。毫无疑问,未来的每一个版本都可能打破这一切。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多