Я внедрил Index Indexer для класса адаптера, который расширяет BaseAdapter. Теперь для первого запуска Index Indexer показывает наложение правильно. Но когда содержимое списка обновляется, раздел Overlay не обновляется и дает ArrayOutOfBoundException. Для одного исправить то, что я сделал, я сделал listview.setFastScrollEnabled(false); обновить содержимое адаптера; а затем listview.setFastScrollEnabled(true); Теперь случается, что оверлей обновляется, но Overlay приближается к левой верхней части списка. Как я могу это исправить.
Раздел Indexer Overlay не обновляется по мере изменения данных адаптера
Ответ 1
небольшое обходное решение, предложенное lee.wilmot,
private void jiggleGrid() {
int newWidth = flag( FLAG_THUMB_PLUS ) ?
FrameLayout.LayoutParams.FILL_PARENT :
grid.getWidth() - 1;
FrameLayout.LayoutParams l = new FrameLayout.LayoutParams(
newWidth,
FrameLayout.LayoutParams.FILL_PARENT
);
grid.setLayoutParams( l );
toggleFlag( FLAG_THUMB_PLUS );
}
Флаг и toggleFlag - это некоторые функции.
Вызвать этот метод после установки setFastScrollEnabled(true);
. Это сработало для меня....
Ответ 2
Думаю, что я поделился бы готовой версией описанного выше решения для ListActivity:
private boolean FLAG_THUMB_PLUS = false;
private void jiggleWidth() {
ListView view = getListView();
if (view.getWidth() <= 0)
return;
int newWidth = FLAG_THUMB_PLUS ? view.getWidth() - 1 : view.getWidth() + 1;
ViewGroup.LayoutParams params = view.getLayoutParams();
params.width = newWidth;
view.setLayoutParams( params );
FLAG_THUMB_PLUS = !FLAG_THUMB_PLUS;
}
Работает для меня.
Ответ 3
Чтобы он работал во всех случаях (особенно с макетом FILL_PARENT и изменением ориентации), вместо использования ListView напрямую используйте этот класс и вызывайте invalidateSectionIndexer() после изменения вашего адаптера.
class MyListView extends ListView {
public MyListView(Context context) {
super(context);
}
public void invalidateSectionIndexer() {
// 1. this invalidates the Section Indexer
super.setFastScrollEnabled(false);
// Your adapter might be wrapped, e.g. when adding headers/footers.
ListAdapter adapter = getAdapter();
BaseAdapter baseAdapter = (adapter instanceof WrapperListAdapter) ?
(BaseAdapter) ((WrapperListAdapter) adapter).getWrappedAdapter() :
(BaseAdapter) adapter;
baseAdapter.notifyDataSetChanged();
super.setFastScrollEnabled(true);
// 2. This fixes the android bug of section overlay not positioned correctly.
int width = getWidth();
int height = getHeight();
super.onSizeChanged(width, height, width, height);
}
}
Ответ 4
Выше решения в порядке, за исключением случая, когда ширина установлена на FILL_PARENT. Чтобы заставить их работать для этого случая, вы должны переопределить onSizeChanged как это
@Override
protected void onSizeChanged (int w, int h, int oldw, int oldh)
{
super.onSizeChanged( w , h , oldw , oldh );
if ( mInstance.getLayoutParams().width != FrameLayout.LayoutParams.FILL_PARENT )
{
mInstance.post( new Runnable()
{
@Override
public void run()
{
mInstance.setLayoutParams( new FrameLayout.LayoutParams( FrameLayout.LayoutParams.FILL_PARENT , FrameLayout.LayoutParams.FILL_PARENT ) );
}
});
}
}
При этом размер модификации будет одобрен после изменения ориентации экрана.
Ответ 5
У меня возникла аналогичная проблема, используя ResourceCursorAdapter. Раздел indexer не обновлялся после того, как был установлен новый адаптер для списка или метод swapCursor() для обновления курсора. Я пробовал все решения, размещенные на StackOverflow, без каких-либо успехов. Только работающий обходной путь, который я нашел, заключается в том, что вам нужно отсоединить/присоединить фрагмент, который вы хотите обновить (вам нужно запустить метод фрагмента onCreateView(), где вы создаете свой пользовательский интерфейс) после обновления моего курсора ( а не CursorAdapter.. вам нужно обновить/установить адаптер в onCreateView()). Это сработало для меня. Вот код, который я использую для повторного прикрепления фрагмента.
fragmentManager.beginTransaction().detach(frag).attach(frag).commitAllowingStateLoss();
Вы также можете попытаться удалить соответствующий listView из макета и снова добавить его в макет, но я использовал некоторые проблемы, используя этот подход.