【问题标题】:ListView does not show changes until focus changes after notifyDataSetChanged在 notifyDataSetChanged 之后焦点更改之前,ListView 不会显示更改
【发布时间】:2015-08-05 10:55:18
【问题描述】:

我有一个AlertDialog 和一个ListView 设置为多选。它上面还有一个Button

Button打开另一个AlertDialog,如果ok'ed将从ListView的数据集中删除选中的项目,然后告诉列表视图的适配器数据集已经随着@987654327而改变@方法。

这一切都很好,除了一件事。 ListView 在我与某些东西交互之前不会更新它的内容。然后它会更新为正确的数据。

这不是一个大问题,但我真的希望ListView 立即显示正确,而不是在焦点改变之后。

代码:

Button remove = (Button) view.findViewById(R.id.btn_remove_questions_edit_rack);
    final Context con = this;
    remove.setOnClickListener(new OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            Builder warnBuild = new Builder(con);
            warnBuild.setMessage(R.string.question_deletion_warning);
            warnBuild.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialog, int which)
                {
                    SparseBooleanArray checked = list.getCheckedItemPositions();
                    for (String s : keys)
                    {
                        int i = keys.indexOf(s);
                        if (checked.get(i))
                        {
                            toRemove.add(map.get(s));
                            map.remove(s);
                        }
                    }
                    keys.clear();
                    keys.addAll(map.keySet());
                    ((ArrayAdapter) list.getAdapter()).notifyDataSetChanged();
                    list.clearChoices(); //This makes sure the selection is cleared, if it isn't, some of the other items (those that now has the index of the selected items) will be selected when the View refreshes.
                    dialog.dismiss();
                }
            });

            //Negative button here, not relevant.
        }
    });

mapkeys 分别是:

final HashMap<String, QualityQuestion> map = new HashMap<>();
//I add items to the map
final ArrayList<String> keys = new ArrayList<>(map.keySet());

toRemove 是我存储要从它们所在的实际对象中删除的项目的位置,当按下原始 AlertDialog 上的确定按钮时。

这就是我首先填充我的ListView 的方式:

final ListView list = (ListView) view.findViewById(R.id.list_questions_edit_rack);
    list.setAdapter(
            new ArrayAdapter<String>(this,
                    android.R.layout.simple_list_item_activated_1,
                    keys));

我已经尝试过list.invalidateViews()list.invalidate 之类的东西,以及我在 SO 上与我的问题类似的问题中发现的其他东西。但这些都没有任何区别。我怀疑我的问题与他们的不同,因为我的项目显然已更新,只需将焦点更改为原始 AlertDialog 即可看到更改。

如何让ListView 在焦点更改后立即显示其数据源中的更改?

【问题讨论】:

    标签: android android-listview android-alertdialog notifydatasetchanged


    【解决方案1】:

    通过调用

    ((ArrayAdapter) list.getAdapter()).notifyDataSetChanged();
    

    你得到一个新的适配器,它几乎肯定与你最初用来填充列表的匿名适配器不同。

    另请参阅ListView.getAdapter() 的文档

    返回当前在此 ListView 中使用的适配器。 返回的适配器可能与传递给 setAdapter(ListAdapter) 的适配器不同,但可能是 WrapperListAdapter。

    从这个新适配器的角度来看,数据集没有改变,因为改变发生在它被实例化之前。

    要解决您的问题,请将您的列表和您的列表适配器成员加入您的活动类(或您希望让它们保持活动的范围):

    private ArrayList<String>    keys;
    private ArrayAdapter         myAdapter;
    private ListView             list;
    

    然后在你的“onCreate()”中

    keys = ...;     // initialization of ArrayList with the needed data 
    myAdapter = new ArrayAdapter<String>(this,
                        android.R.layout.simple_list_item_activated_1,
                        keys);
    list = (ListView) view.findViewById(R.id.list_questions_edit_rack);
    list.setAdapter(myAdapter);
    

    这样,您可以在“OnClickListener”中通知“myAdapter”:

    keys.addAll(map.keySet());
    myAdapter.notifyDataSetChanged();
    

    希望这会有所帮助:)

    【讨论】:

    • 哦,有道理!会尝试:)
    【解决方案2】:

    您可以调整它,将焦点授予另一个视图,然后再请求它:

    view.requestFocus();
    

    你也可以使用:

    view.requestFocusFromTouch();
    

    【讨论】:

    • 不,不起作用。与至少包含所有元素的View 不同。
    • 也不会请求焦点到被按下的Button
    • 或到 ListView。或者到按钮,然后是 ListView。
    • 顺便说一句,即使我用list.clearChoices()解决了这个问题,选择另一个项目的问题也会再次出现
    • 当按钮被按下时它应该获得焦点。为什么按下按钮后 listView 会获得焦点?
    猜你喜欢
    • 2019-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多