Ответ 1
Это преднамеренное поведение FastScroller
. Когда вы вызываете setAdapter
на ListView
, адаптер заключен в HeaderViewListAdapter
, если есть какие-либо заголовки; поэтому вы должны называть addHeaderView
до setAdapter
. Затем в коде 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
, если это необходимо для ведения бухгалтерского учета), вместо использования механизма заголовка?