【问题标题】:Calling notifyDataSetChanged from inside adapter fails从适配器内部调用 notifyDataSetChanged 失败
【发布时间】:2012-11-17 02:24:46
【问题描述】:

我有一个适配器(扩展 BaseAdapter),我试图从中调用 notifyDataSetChanged(),但它不工作。我相信 notifyDataSetChanged() 实际上是被调用的,基于使用 Eclipse 调试器进入它。但是,它不调用 getView()。我的适配器底层的数据正在改变,这是应该的。我在适配器中有一个方法 updateSettings(),用于更新适配器底层的数据。如果我从我的 ListViewActivity 调用 updateSettings(),我没有任何问题...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()" );
    }

感谢任何见解!

谢谢。

【问题讨论】:

    标签: java android adapter


    【解决方案1】:

    我只是添加

    adapter.notifyDataSetChanged()

    onCLick里面的onBindViewHolder(),对我有用~

    【讨论】:

      【解决方案2】:

      只需添加

      notifyDataSetChanged()

      ** 在您的适配器中,应用程序将重新加载您的列表。

      ^^

      【讨论】:

        【解决方案3】:

        我遇到了同样的问题,解决方法是: 不要在适配器内部调用NotifyDataSetChanged() 使用listView.getAdapter().notiftDataSetChanged()调用它

        它会起作用的。

        【讨论】:

        • 你能解释一下你把那行“listView.getAdapter().notiftDataSetChanged()”放在哪里吗? THX
        【解决方案4】:

        你必须用这种方式调用notifyDataSetChanged():

        ArrayAdapter<String> adapter; // where adapter - your adapter
        adapter = new ArrayAdapter<String>(...);
        adapter.notifyDataSetChanged();
        

        【讨论】:

        • 谢谢。这有助于我开发解决问题的方法,因为我知道我必须从适配器外部调用。
        【解决方案5】:

        感谢所有关注我问题的人。我希望这个解决方案可以帮助其他人。

        我正在为一个单独的列表使用适配器,它管理列表不同部分的适配器。我遇到问题的适配器是托管适配器之一。

        我所做的是创建一个回调函数(在 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();
            }
        }
        

        谢谢:)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-11-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多