java 从适配器内部调用 notifyDataSetChanged 失败

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13427069/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 12:40:15  来源:igfitidea点击:

Calling notifyDataSetChanged from inside adapter fails

javaandroidadapter

提问by user1791622

I have an adapter (extends BaseAdapter) from which I'm trying to call notifyDataSetChanged(), but it's not working. I believe notifyDataSetChanged() is actually being called, based on stepping into it using the Eclipse debugger. However, it doesn't call getView(). The data underlying my adapter is being changed, as it should. I have a method, updateSettings(), in the adapter that updates the data underlying the adapter. If I call updateSettings() from my ListViewActivity, I don't have any problem...notifyDataSetChanged() behaves as I expect. But when I call updateSettings() from within the adapter, notifyDataSetChanged() doesn't work. Am I doing something fundamentally wrong by trying to call notifyDataSetChanged() from within an adapter? Here is some code I have:

我有一个适配器(扩展 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;

}

In this block, I set up the row view and attach event handlers to the SeekBar. What I want to happen is that when someone scrolls the SeekBar, it updates the text above it. Here is my updateSettings() method:

在这个块中,我设置了行视图并将事件处理程序附加到 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()" );
    }

Any insight is appreciated!

任何见解表示赞赏!

Thank you.

谢谢你。

回答by Terranology

Just add

只需添加

notifyDataSetChanged()

notifyDataSetChanged()

** inside your Adapter and the app'll reload your list.

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

^^

^^

回答by Mahmoud

The same problem I've had, the solution is : Don't call NotifyDataSetChanged()inside the adapter call it using the listView.getAdapter().notiftDataSetChanged()

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

it will work .

它会工作。

回答by ??i B?p

I just add

我只是添加

adapter.notifyDataSetChanged()

适配器.notifyDataSetChanged()

inside onCLick in onBindViewHolder(), it's work for me~

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

回答by Artyom Kiriliyk

You must call notifyDataSetChanged()in this way:

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

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

回答by user1791622

Thanks to everyone who looked at my problem. I hope this solution helps other people.

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

I was using an adapter for a separated list, which manages adapters for the different sections of the list. The adapter I was having problem with, was one of the managed adapters.

我将适配器用于单独的列表,它管理列表不同部分的适配器。我遇到问题的适配器是托管适配器之一。

What I did was make a callback function (in Java) that handles the situation when the SeekBar is scrolled. I registered it with my adapter, so when it's called, it calls adapter.notifyDataSetChanged:

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

Thanks :)

谢谢 :)