Сбой вызова notifyDataSetChanged из внутреннего адаптера

У меня есть адаптер (расширяет BaseAdapter), из которого я пытаюсь вызвать notifyDataSetChanged(), но он не работает. Я считаю, что на самом деле вызывается notifyDataSetChanged(), основанный на входе в него с помощью отладчика Eclipse. Однако он не вызывает getView(). Данные, лежащие в основе моего адаптера, изменяются, как и должно быть. У меня есть метод updateSettings() в адаптере, который обновляет данные, лежащие в основе адаптера. Если я вызываю updateSettings() из своей ListViewActivity, у меня нет проблем... notifyDataSetChanged() ведет себя так, как я ожидаю. Но когда я вызываю updateSettings() из адаптера, notifyDataSetChanged() не работает. Я делаю что-то принципиально неправильное, пытаясь вызвать notifyDataSetChanged() из адаптера? Вот какой код у меня есть:

public View getView( int position, View convertView, ViewGroup parent )
{
    Log.d( CLASS_NAME, "Entered getView()" );
    View row = convertView;
    _settingViewHolder = new PhoneSettingViewHolder();
    final int index = position;

    /* If this is the first time the list is being built, get all of the UI widgets
     * and store them in a PhoneSettingViewHolder object for future use on
     * subsequent writing of the list.
     */
    if( row == null )
    {
        LayoutInflater inflater = (LayoutInflater)_context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
        row = inflater.inflate( R.layout.phone_list_complex, null, false ); 

        _settingViewHolder.txtSettingName = (TextView)row.findViewById( R.id.phone_list_complex_title );
        _settingViewHolder.txtSettingValue = (TextView)row.findViewById( R.id.phone_list_complex_caption );
        _settingViewHolder.sbTimeout = (SeekBar)row.findViewById( R.id.slider );
        _settingViewHolder.txtPercent = (TextView)row.findViewById( R.id.percent );

        _settingViewHolder.sbTimeout.setMax( 30 );
        _settingViewHolder.sbTimeout.setProgress( 1 );

        // associate this PhoneSettingViewHolder object with the row
        row.setTag( _settingViewHolder );
    }
    else
    {
        // get the PhoneSettingViewHolder object that is associated with this row
        _settingViewHolder = (PhoneSettingViewHolder)row.getTag();
    }

    // get Setting object and store values in PhoneSettingViewHolder object
    final Setting setting = _settings.get( position );
    _settingViewHolder.txtSettingName.setText( setting.getSettingName() );
    Log.d( CLASS_NAME, "setting.getSettingValue() = " + setting.getSettingValue() );
    _settingViewHolder.txtSettingValue.setText( setting.getSettingValue() );

    /* Event handlers for SeekBar */
    _settingViewHolder.sbTimeout.setOnSeekBarChangeListener( new OnSeekBarChangeListener() {
        public void onProgressChanged( SeekBar seekBar, int progress, boolean isUser )
        {
            Log.d( CLASS_NAME, "Entered onProgressChanged()" );
            String percent = String.valueOf( progress );
            updateSettings( index, percent );
        }

        public void onStartTrackingTouch( SeekBar seekBar )
        {
            // Nothing to do here
        }

        public void onStopTrackingTouch( SeekBar seekBar )
        {
            // Nothing to do here 
        }
    });


    return row;

}

В этом блоке я настраиваю представление строк и прикрепляю обработчики событий к SeekBar. Что я хочу, так это то, что когда кто-то прокручивает SeekBar, он обновляет текст над ним. Вот мой метод updateSettings():

    public void updateSettings( int index, String progress ) 
    {
        Log.d( CLASS_NAME, "Entered updateSettings()" );
        Setting setting = new Setting( SETTING_NAME, progress );
        _settings.set( index, setting );
        Log.d( CLASS_NAME,  "Calling notifyDataSetChanged()" );
        notifyDataSetChanged();
        Log.d( CLASS_NAME, "Returned from notifyDataSetChanged()" );
    }

Любое понимание ценится!

Спасибо.


person user1791622    schedule 17.11.2012    source источник


Ответы (5)


Просто добавь

уведомитьDataSetChanged()

** внутри вашего адаптера, и приложение перезагрузит ваш список.

^^

person Terranology    schedule 01.04.2016

Та же проблема, что и у меня, решение: не вызывайте NotifyDataSetChanged() внутри адаптера, вызывайте его с помощью listView.getAdapter().notiftDataSetChanged()

это сработает .

person Mahmoud    schedule 28.05.2013
comment
Можете ли вы объяснить, куда вы поместили эту строку listView.getAdapter().notiftDataSetChanged()? Спасибо - person Terranology; 01.04.2016

я просто добавляю

адаптер.notifyDataSetChanged()

внутри onCLick в onBindViewHolder(), у меня это работает~

person Quang Dai Ngo    schedule 02.10.2017

Вы должны вызвать notifyDataSetChanged() таким образом:

ArrayAdapter<String> adapter; // where adapter - your adapter
adapter = new ArrayAdapter<String>(...);
adapter.notifyDataSetChanged();
person Artyom Kiriliyk    schedule 18.11.2012
comment
Спасибо. Это помогло мне разработать решение моей проблемы, потому что я знаю, что должен был звонить из-за пределов адаптера. - person user1791622; 20.11.2012

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

Я использовал адаптер для отдельного списка, который управляет адаптерами для разных разделов списка. Адаптер, с которым у меня возникла проблема, был одним из управляемых адаптеров.

Что я сделал, так это сделал функцию обратного вызова (на Java), которая обрабатывает ситуацию, когда SeekBar прокручивается. Я зарегистрировал его с помощью своего адаптера, поэтому при его вызове вызывается adapter.notifyDataSetChanged:

public void eventNotifier( InterestingEvent event )
{
    _event = event; // register event handler
}

class NotifyDataSetChangedEvent implements InterestingEvent {

    private final String CLASS_NAME = "NotifyDataSetChangedEvent";

    public void interestingEventHappened()
    {
        Log.d( CLASS_NAME, "Entered interestingEventHappened()");
        _adapter.notifyDataSetChanged();
    }
}

Спасибо :)

person user1791622    schedule 19.11.2012