Перебор элементов списка и изменение дочерних представлений

1
listView.setOnItemClickListener(new OnItemClickListener(){

    @Override
    public void onItemClick(AdapterView<?> parent, View viewItem, int position, long arg3) {


        for(int i =parent.getFirstVisiblePosition(); i <parent.getLastVisiblePosition(); i ++)
        {
            Log.i("in", Integer.toString(i));
            View v = parent.getChildAt(i);

            ((Button)v.findViewById(R.id.removefav)).setVisibility(View.INVISIBLE);
            ((Button)v.findViewById(R.id.gotherefav)).setVisibility(View.INVISIBLE);


        }
        viewItem=listView.getChildAt(position);
        ((Button)viewItem.findViewById(R.id.removefav)).setVisibility(View.VISIBLE);
        ((Button)viewItem.findViewById(R.id.gotherefav)).setVisibility(View.VISIBLE);
        TextView text = (TextView)viewItem.findViewById(R.id.item);
        name = text.getText();

Этот код работает, если вы нажимаете на элементы, которые видны при первом запуске ListView, но если вы прокручиваете и имеете, скажем, половину видимого элемента, выбрасывает NullpointerException:

07-02 18:38:47.290: WARN/dalvikvm(6078): threadid=3: thread exiting with uncaught exception (group=0x4001b188)
07-02 18:38:47.290: ERROR/AndroidRuntime(6078): Uncaught handler: thread main exiting due to uncaught exception
07-02 18:38:47.300: ERROR/AndroidRuntime(6078): java.lang.NullPointerException
07-02 18:38:47.300: ERROR/AndroidRuntime(6078):     at walk.me.Tabber$1.onItemClick(Tabber.java:89)
07-02 18:38:47.300: ERROR/AndroidRuntime(6078):     at android.widget.AdapterView.performItemClick(AdapterView.java:284)
07-02 18:38:47.300: ERROR/AndroidRuntime(6078):     at android.widget.ListView.performItemClick(ListView.java:3285)
07-02 18:38:47.300: ERROR/AndroidRuntime(6078):     at android.widget.AbsListView$PerformClick.run(AbsListView.java:1640)
07-02 18:38:47.300: ERROR/AndroidRuntime(6078):     at android.os.Handler.handleCallback(Handler.java:587)
07-02 18:38:47.300: ERROR/AndroidRuntime(6078):     at android.os.Handler.dispatchMessage(Handler.java:92)
07-02 18:38:47.300: ERROR/AndroidRuntime(6078):     at android.os.Looper.loop(Looper.java:123)
07-02 18:38:47.300: ERROR/AndroidRuntime(6078):     at android.app.ActivityThread.main(ActivityThread.java:4363)
07-02 18:38:47.300: ERROR/AndroidRuntime(6078):     at java.lang.reflect.Method.invokeNative(Native Method)
07-02 18:38:47.300: ERROR/AndroidRuntime(6078):     at java.lang.reflect.Method.invoke(Method.java:521)
07-02 18:38:47.300: ERROR/AndroidRuntime(6078):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
07-02 18:38:47.300: ERROR/AndroidRuntime(6078):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
07-02 18:38:47.300: ERROR/AndroidRuntime(6078):     at dalvik.system.NativeStart.main(Native Method)

Я пытаюсь сделать это, у меня есть ListView и две кнопки. И пользователь касается одного из элементов, отображаемых дочерними представлениями (двумя кнопками), когда пользователь касается другого элемента, кнопки на ранее выбранном элементе исчезают.

Что я делаю неправильно? Этот элемент "полувидимый" (когда прокручивается список) делает NPE? Я также пытался начать с

i=0

но это было то же самое.

Теги:
listview
parent-child

1 ответ

3
Лучший ответ

Вы не должны изменять представления, подобные этому в ListView. Просмотр списка в android всегда поддерживается адаптером и оптимизирован таким образом, что представления повторно используются, когда они прокручиваются из экрана. Это означает, что вы всегда должны иметь getView(), реализованный в адаптере, который должен отражать, как данные (модель в адаптере) представлены в представлении. Важно правильно реагировать, когда вы получаете представление о переработке в параметрах getView (т.е. Не создавать его с нуля, а вместо того, чтобы устанавливать соответствующие поля, тексты, видимость и т.д. В соответствии с элементом из адаптера, соответствующего представлению),

Всякий раз, когда вы изменяете все соответствующие данные в адаптере (меняйте флаг, указывающий на видимость в вашем случае), вы должны вызывать notifyDataSetChanged() на адаптере, а затем listview будет воссоздавать все видимые элементы самостоятельно (он будет проходить через них и вызовите getView(), повторно используя созданные ранее представления.

Посмотрите также на Android listActivity onListItemClick с CheckBox, который охватывает аналогичную проблему.

  • 0
    Вызов .notifyDataSetChanged () вызовет getView (), поэтому элементы будут обновлены и будут применены предыдущие настройки (настройки видимости)?
  • 0
    Ага. NotifyDataSetChange будет эффективно переводить в Для всех видимых элементов: nowUsedView = getView (currentView, position, ...)
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню