這是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
時有條件地在其他幾個函數中有效。如果onSectionsChanged
被調用,則mListAdapter
僅爲空,因此我們暫時忽略該路徑。
經過大量的挖掘,並與各種反射掛鉤玩,我可以說,沒有辦法做到這一點,即使稍有未來兼容。您可以使用反射來替換HeaderViewListAdapter,以使其位於其標題計數等位置;但這是相當脆弱的。同樣的,你可以將(包可見的)FastScroller與你自己的行爲進行子類化;但mListOffset
被廣泛引用,而不是通過getter,所以這比平常更醜。基本上,你遇到了一個事實,即系統不能按照你想要的方式工作。
我毫不猶豫地稱這是一個錯誤,因爲它從代碼中清楚地知道它是故意的行爲。你是否考慮過讓列表的第一個元素只是一個特殊的第一個元素(可能使用自定義WrapperListAdapter
,如果需要用於簿記),而不是使用標題機制?
你有沒有發現如何解決這個問題? – clauziere