[done] notifyDataSetChanged() не обновляет ListActivity автоматически

У меня есть некоторые проблемы с notifyDataSetChanged() базового адаптера. Этот метод вызывается в refreshItems() и обновляет BaseAdapter моего ListActivity. При вызове notifyDataSetChanged() ничего не происходит, пока я не прокручу вниз ListView, например, с помощью клавиш со стрелками. Как-то модифицированный метод getView() также не вызывается. Может быть, вы можете дать мне подсказку - спасибо!:)

public class WinampControlClientPlaylist extends ListActivity {

static WinampControlClientPlaylist activity = null;

static EfficientAdapter adapter = null;


static class EfficientAdapter extends BaseAdapter {


    public EfficientAdapter(Context context) {
        mInflater = LayoutInflater.from(context);
    }

    private LayoutInflater mInflater;

    @Override
    public int getCount() {
        return Settings.playlistlength;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder;


        if (convertView == null) 
        {
            holder = new ViewHolder();

            convertView = mInflater.inflate(R.layout.listview, null);

            holder.text = (TextView) convertView.findViewById(R.string.playlist_title);
            holder.image = (ImageView) convertView.findViewById(R.string.playlist_play);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }


        holder.text.setText(Settings.playlist[position]);

        if (position == Settings.playlistPosition)
        {
            holder.text.setTypeface(null, Typeface.ITALIC);
            holder.image.setVisibility(0);
        }
        else
        {
            holder.text.setTypeface(null, Typeface.NORMAL);
            holder.image.setVisibility(4);
        }


        return convertView;
    }


    static class ViewHolder {
        TextView text;
        ImageView image;
    }

    @Override
    public Object getItem(int position) {
        return Settings.playlist[position];
    }
}




void initialize()
{
    adapter = new EfficientAdapter(this);
    setListAdapter(adapter);

    //registerForContextMenu(getListView());
}


@Override
public void onResume()
{
    super.onResume();

    // REFRESH PLAYLIST
    if (getListAdapter() == null && Settings.playlist != null)
        initialize();
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.playlist);

    activity = this;
}

static void refreshItems()
{
    try {
        adapter.notifyDataSetChanged();
    } catch (Exception e) {}

}

}

Ответ 1

У меня была та же проблема (обновления ListView только при ее прокрутке, даже notifyDataSetChanged не помогло). Я решу это так: просто попробуйте сделать свои "модификации просмотров" в потоке, который создает ваш пользовательский интерфейс.

activity.runOnUiThread(new Runnable() {         
        public void run() {
              //do your modifications here

              // for example    
              adapter.add(new Object());
              adapter.notifyDataSetChanged()  
        }
});

Ответ 2

Как отметил Франко, notifyDataSetChanged() используется, чтобы сообщить ListView, что содержимое его адаптера изменилось, а не то, что ему нужно перерисовать. Вы просто меняете настройку, которая влияет на то, как что-то отображается. Попробуйте вызвать refreshDrawableState, чтобы сообщить, что список перерисовывается.

Ответ 3

Попробуйте вызвать invalidate() в вашем ListView.

Ответ 4

Я думаю, что могут возникнуть проблемы с адаптером; возможно, он не установлен.

По моему опыту, всегда существовала какая-то причина, которая мешала обновлению списка (и адаптера).

Ответ 5

У меня была такая же проблема, и решение для меня состояло в вызове requestLayout() в ListView.

Ответ 7

У меня возникла та же проблема, и я попытался вызвать notifyDataSetChanged() на адаптере. Кроме того, я также пытался называть refreshDrawableState(), invalidateViews() на просмотр, и никто из них не работал. Все эти методы вызывают в потоке пользовательского интерфейса. Затем я нашел это Как очистить представления, которые хранятся в RecycleBin ListView?. Наконец, setAdapter() работал, только если я создаю новый адаптер.

Ответ 8

Основная причина этого - неправильная ссылка адаптера, на который вы вызываете notifyDataSetChanged();

Я думаю, вам нужно убедиться, что вы один раз создаете объект-адаптер и вызываете notifyDataSetChanged() на том же объекте.

Вы можете отлаживать эталонное значение объекта при создании времени объекта адаптера и когда вы вызываете метод notifyDataSetChanged().

Ответ 9

Why it works in first code ?

--- Поскольку вы устанавливаете значения для временного списка и передаете ему адаптер, и он показывает его в список.

Why not work in second code ?

--- Потому что вы устанавливаете temp для адаптера задолго до того, как вы установите значение в temp во-вторых, ваш класс адаптера может не получить обновленное значение, когда вы устанавливаете новое значение для temp.., потому что temp не является общедоступным или нет на уровне класса или не статичным. Поместите объявление temp на уровне root и попробуйте.

И, пожалуйста, покажите свой полный код столько, сколько требуется, и Logcat, если вы получаете предупреждения, кроме того.