これはFastScroller
の意図的な動作です。 ListView
でsetAdapter
を呼び出すと、ヘッダーが設定されている場合、アダプタはHeaderViewListAdapter
にラップされます。このため、addHeaderView
の前にsetAdapter
に電話する必要があります。その後、FastScroller
コードでは、我々は、次を参照してください。
ある
if (adapter instanceof HeaderViewListAdapter) {
mListOffset = ((HeaderViewListAdapter)adapter).getHeadersCount();
adapter = ((HeaderViewListAdapter)adapter).getWrappedAdapter();
}
は、オフセット取得し、根本的なアダプタを使用します。 mListOffset
を使用して、高速スクロールでスクロールするための先頭位置を設定します。では、実際にこのラッピングはどこで行われますか?だから我々は間違いなく正しい場所を中心に探している
if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
} else {
mAdapter = adapter;
}
:我々が見るListView.addHeaderView
、予想通り、まで。今、あなたの目標はあなたの速い親指のためのリストヘッダーのオフセット動作を持たないことですが、そうでなければヘッダーを持つ通常のリストを持つように思えます。これを行うには、(コードの内容に基づいて)FastScroller.mListOffset = 0
で十分です。これはgetSectionsFromIndexer
でのみ設定され、init
では無条件と、mListAdapter == null
では条件付きでのみいくつかの他の関数で設定されます。 onSectionsChanged
が呼び出された場合ははnullになりますので、ここでそのパスを無視しましょう。
多くの掘り出し物や様々な反射フックで遊んだ後で、私はこれを行う方法がないと言えるでしょうが、それは少しでも将来の互換性があります。リフレクションを使用して、HeaderViewListAdapterをヘッダーカウントなどに置き換えることができます。しかし、それはかなり壊れやすいです。同様に、(パッケージが可視の)FastScrollerを独自の振る舞いでサブクラス化することもできます。 mListOffset
はゲッターではなく広く参照されるため、これは通常よりも醜いです。基本的には、あなたが望むようにシステムがうまく動作しないという事実に反して走っています。
コードからは意図的な動作であることが分かりましたので、私はこれをバグと呼んでいます。ヘッダーのメカニズムを使用するのではなく、リストの最初の要素を特別な最初の要素にすることを検討しましたか(おそらく、のようなカスタムWrapperListAdapter
を使用しています)。
この問題を解決する方法を見つけたことがありますか? – clauziere