12

デバイスのリストを表示するために使用している ListView で構成される画面を備えた Android アプリがあります。これらのデバイスは配列に保持されます。

ArrayAdapter を使用して、画面上の配列にあるものをリストで表示しようとしています。

SetupActivityクラスを最初にロードすると機能しますが、 addDevice()メソッドに新しいデバイスを追加する機能があります。これは、デバイスを保持する配列が更新されることを意味します。

リストを更新するはずのnotifyDataSetChanged()を使用していますが、機能していないようです。

public class SetupActivity extends Activity
{   
    private ArrayList<Device> deviceList;

    private ArrayAdapter<Device> arrayAdapter;

    private ListView listView;

    private DevicesAdapter devicesAdapter;

    private Context context;

    public void onCreate(Bundle savedInstanceState)  //Method run when the activity is created
    {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.setup);  //Set the layout

        context = getApplicationContext();  //Get the screen

        listView = (ListView)findViewById(R.id.listView);

        deviceList = new ArrayList<Device>();

        deviceList = populateDeviceList();  //Get all the devices into the list

        arrayAdapter = new ArrayAdapter<Device>(this, android.R.layout.simple_list_item_1, deviceList);

        listView.setAdapter(arrayAdapter);  
    }

    protected void addDevice()  //Add device Method (Simplified)
    {
        deviceList = createNewDeviceList();    //Add device to the list and returns an updated list

        arrayAdapter.notifyDataSetChanged();    //Update the list
}
}

誰が私が間違っているのかを見ることができますか?

4

3 に答える 3

39

ArrayAdapter の場合、アダプタで 、、、および関数notifyDataSetChangedを使用する場合にのみ機能します。addinsertremoveclear

  1. clear を使用してアダプタをクリアします -arrayAdapter.clear()
  2. Adapter.addAll を使用して、新しく形成されたリストを追加します -arrayAdapter.addAll(deviceList)
  3. notifyDataSetChanged を呼び出します

代替案:

  1. 新しいデバイスリストが作成されたら、この手順を繰り返します - ただし、これは冗長です

    arrayAdapter = new ArrayAdapter<Device>(this, android.R.layout.simple_list_item_1, deviceList);
    
  2. BaseAdapter および ListAdapter から派生した独自のクラスを作成して、柔軟性を高めます。これが最も推奨されます。
于 2012-11-07T18:02:26.333 に答える
12

受け入れられた答えは問題を解決しますが、理由の説明は正しくありません。これは重要な概念であるため、明確にしようと思いました。

アダプターで 、、、またはが呼び出された notifyDataSetChanged()場合にのみ機能するSlartibartfast の説明は正しくありません。addinsertremoveclear

その説明はメソッドにも当てはまります。true に設定すると (デフォルトで) 、これら 4 つのアクションのいずれかが発生したとき setNotifyOnChange()に自動的に呼び出されます。notifyDataSetChanged()

ポスターは2つの方法を混同したと思います。 notifyDatasetChanged()自体にはこれらの制限はありません。これは、対象のリストが変更されたことをアダプターに通知するだけであり、リストへの変更が実際にどのように発生したかは関係ありません。

のソース コードを確認できませんcreateNewDeviceList()が、作成した元のリストを参照するアダプタがあり、次に で新しいリストを作成しcreateNewDeviceList()、アダプタがまだ古いリストでは変更を確認できませんでした。

言及されたソリューション slartibartfast は、アダプターをクリアし、特に更新されたリストをそのアダプターに追加するため機能します。したがって、アダプタが間違った場所を指しているという問題はありません。

これが誰かを助けることを願っています!

于 2014-09-05T06:34:59.113 に答える
0

メソッド addDevice が無限ループを引き起こしています。ここで行っているように、それ自体からメソッドを呼び出さないでください:

deviceList = addDevice();
于 2012-11-07T17:30:57.857 に答える