在notifyDataSetChanged之后焦点更改之前,ListView不会显示更改

时间:2015-08-05 10:55:18

标签: android android-listview android-alertdialog notifydatasetchanged

我有一个AlertDialogListView设置为多个选择。它上面还有一个Button

Button打开另一个AlertDialog,如果确定,则会从ListView的数据集中删除所选项目,然后告诉适配器列表视图数据集已使用notifyDataSetChanged()方法更改。

这一切都很好,除了一件事。在我与某些内容进行互动之前,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显示焦点变化后imidiatly insted的数据源中的变化?

2 个答案:

答案 0 :(得分:2)

致电

((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();

希望这会有所帮助:)

答案 1 :(得分:0)

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

    ArrayList<WiFiItem> listWifi = new ArrayList<WiFiItem>();
    wifiManager.startScan();
    scanResult = wifiManager.getScanResults();        
    for(ScanResult sc : scanResult) {
        WiFiItem wifiItem = new WiFiItem();
        wifiItem.setSSID(sc.SSID);
        wifiItem.setBSSID(sc.BSSID);           
        listWifi.add(wifiItem);
    }

您也可以使用:

view.requestFocus();