Наложение индексатора раздела не обновляется при изменении данных адаптера - PullRequest
9 голосов
/ 26 мая 2010

Я реализовал секционный индексатор для класса адаптера, который расширяет BaseAdapter. Теперь для первого запуска Indexer Index корректно отображается наложение. Но когда содержимое списка обновляется, наложение раздела не обновляется и выдает ArrayOutOfBoundException. Для одного исправления я сделал listview.setFastScrollEnabled (false); обновить содержимое адаптера; и затем listview.setFastScrollEnabled (true); Теперь происходит обновление наложения, но наложение идет слева вверху списка. Как я могу это исправить.

Ответы [ 5 ]

8 голосов
/ 01 апреля 2011

Думаю, я поделюсь готовой версией вышеупомянутого обходного пути для 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;
}

У меня работает.

5 голосов
/ 03 февраля 2012

Чтобы заставить его работать во всех случаях (особенно с изменением макета и ориентации 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);
    }
}
1 голос
/ 01 июля 2010

небольшой обходной путь, предложенный 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 );
  }

flag и toggleFlag - некоторые функции.

Вызовите этот метод после установки setFastScrollEnabled(true);. У меня это сработало ....

0 голосов
/ 04 января 2016

У меня похожая проблема при использовании ResourceCursorAdapter . Индексатор разделов не обновлялся после установки нового адаптера для списка или вызова метода swapCursor () для обновления курсора. Я испробовал все решения, размещенные на StackOverflow, но безуспешно. Единственный работающий обходной путь, который я обнаружил, заключается в том, что вам нужно отсоединить / прикрепить фрагмент, который вы хотите обновить (вам нужно вызвать onCreateView () метод фрагмента, в котором вы создаете свой пользовательский интерфейс) после того, как я обновлю свой курсор (не CursorAdapter .. вам нужно обновить / установить адаптер в onCreateView ()). Это сработало для меня. Вот код, который я использую, чтобы прикрепить фрагмент.

fragmentManager.beginTransaction().detach(frag).attach(frag).commitAllowingStateLoss();

Вы также можете попытаться удалить соответствующий listView из макета и снова добавить его в макет, но я столкнулся с некоторыми проблемами при использовании этого подхода.

0 голосов
/ 03 ноября 2011

Вышеуказанные решения приемлемы, за исключением случая, когда ширина установлена ​​в 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 ) );   
            }
        });
    }
}

С этой модификацией размер будет нормальным после изменения ориентации экрана.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...