簡體   English   中英

Android使用新數據更新列表視圖

[英]Android updating listview with new data

我為飛利浦色相燈創建了一個應用程序。 我從REST請求中獲取了數據,並將json響應轉換為燈光。 我將在列表視圖中顯示燈光,一旦按下,您就可以調整飽和度,亮度和色相。 但是在我將這些與PUT請求一起保存到服務器后,它可以工作了。 但是,當我再次單擊指示燈時,數據不會更新。

如何更新列表視圖,使其包含正確的設置?

提前致謝

BridgeTask類:

public class BridgeTask extends AsyncTask<String, Void, String> {
private Bridge bridge;
private BridgeTaskListener listener;
private LightAdapter adapter;

public BridgeTask(BridgeTaskListener listener, Bridge bridge, LightAdapter adapter) {
    this.listener = listener;
    this.bridge = bridge;
    this.adapter = adapter;
}





@Override
protected String doInBackground(String... params) {
    InputStream inputStream = null;
    BufferedReader reader = null;
    String urlString = "";
    String response;

    try {
        URL url = new URL(params[0]);
        URLConnection connection = url.openConnection();


         reader = new BufferedReader(
                new InputStreamReader(
                        connection.getInputStream()));
        response = reader.readLine().toString();
        String line;
        while ((line = reader.readLine()) != null) {
            response += line;
        }
    } catch (MalformedURLException e) {
        Log.e("TAG", e.getLocalizedMessage());
        return null;
    } catch (IOException e) {
        Log.e("TAG", e.getLocalizedMessage());
        return "Ewa";
    } catch (Exception e) {
        Log.e("TAG", e.getLocalizedMessage());
        return null;
    } finally {
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                Log.e("TAG", e.getLocalizedMessage());
                return null;
            }
        }
    }

    return response;
}


}

protected void onPostExecute(String response) {

    try {
        JSONObject albums = new JSONObject(response);

        for(int idx = 1; idx < albums.length() + 1; idx++) {
            String lightId = String.valueOf(idx);
            String description = albums.getJSONObject("" + idx).getString("name");
            JSONObject state = albums.getJSONObject("" + idx).getJSONObject("state");
            int hue = state.getInt("hue");
            int sat = state.getInt("sat");
            int bri = state.getInt("bri");

            Light light = new Light(bridge, lightId, hue, sat, bri);
            light.setDescription(description);
            listener.onLightAvailable(light);


        }


    } catch (JSONException e ) {
        Log.e("TAG", e.getLocalizedMessage());
    }
}

MainActivity類:

public class MainActivity extends AppCompatActivity implements BridgeTaskListener, Serializable, AdapterView.OnItemClickListener {

/**
 * Referentie naar de (singleton) Bridge.
 */
private final Bridge bridge = Bridge.getInstance();

/**
 * Referentie naar de lijst van Light-instanties in de Bridge.
 */
private ArrayList<Light> list = new ArrayList<>();

/**
 * ListView voor de lijst met lampen.
 */
private ListView listView;

/**
 * Adapter voor de ListView.
 */
private LightAdapter adapter;

/**
 * Lifecycle method onCreate()
 *
 * @param savedInstanceState
 */
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    listView = (ListView) findViewById(R.id.lightListView);
    adapter = new LightAdapter(this, getLayoutInflater(), list);
    listView.setAdapter(adapter);
    listView.setOnItemClickListener(this);
    fetchLights();

    adapter.notifyDataSetChanged();



}





/**
 * Implementatie van AdapterView.OnItemClickListener.onItemClick().
 *
 * @param parent
 * @param view
 * @param position
 * @param id
 */
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

    Intent i = new Intent(getApplicationContext(), LightDetailsActivity.class);
    i.putExtra("INDEX", position);
    Bundle args = new Bundle();
    args.putSerializable("LISTARRAY", (Serializable)list);
    i.putExtra("BUNDLE", args);
    startActivity(i);





}

@Override
public void onLightAvailable(Light item) {
    list.add(item);
    adapter.notifyDataSetChanged();


}

@Override
public void onLightError() {

}

private void fetchLights() {

    BridgeTask task = new BridgeTask(this, bridge, adapter);
    String[] urls = new String[]
            {"http://10.0.2.2/api/newdeveloper/lights"};
    task.execute(urls);

}橋梁課:

/**
 * Singleton-referentie.
 */
private static Bridge INSTANCE;

/**
 * Tag t.b.v. logging.
 */
public final String TAG = this.getClass().getName();

/**
 * Basisdeel van url naar Philips Hue Bridge.
 */
private static final String BASE_URL = "http://10.0.2.2/api/newdeveloper";


/**
 * Private constructor (Singleton pattern).
 */
private Bridge() {
}

/**
 * Singleton-referentie.
 *
 * @return steeds dezelfde Bridge-instantie.
 */
public static final Bridge getInstance() {
    if (INSTANCE == null)
        INSTANCE = new Bridge();
    return INSTANCE;
}

/**
 * Retourneer een dummy lijst met lampen. In de volledige versie zouden we hier
 * de Bridge gaan ondervragen over de werkelijk aangesloten lampen (via een
 * HTTP GET op /api/lights).
 *
 * @return lijst van alle aangesloten lampen.
 */



/**
 * Overloaded methode voor schrijven van een boolean-waarde.
 *
 * @param id    lamp id
 * @param key   JSON key
 * @param value JSON boolean-waarde
 */
public void write(String id, String key, boolean value) {
    try {
        JSONObject o = new JSONObject();
        o.put(key, value);
        write(id, o);
    } catch (JSONException e) {
        Log.e(TAG, e.getMessage());
    }
}

/**
 * Overloaded methode voor schrijven van een integer-waarde.
 *
 * @param id    lamp id
 * @param key   JSON key
 * @param value JSON integer-waarde
 */
public void write(String id, String key, int value) {
    try {
        JSONObject o = new JSONObject();
        o.put(key, value);
        write(id, o);
    } catch (JSONException e) {
        Log.e(TAG, e.getMessage());
    }
}

/**
 * Overloaded methode voor schrijven van een String-waarde.
 *
 * @param id    lamp id
 * @param key   JSON key
 * @param value JSON String-waarde
 */
public void write(String id, String key, String value) {
    try {
        JSONObject o = new JSONObject();
        o.put(key, value);
        write(id, o);
    } catch (JSONException e) {
        Log.e(TAG, e.getMessage());
    }
}

/**
 * Private methode om het schrijven van de HTTP REST requests te laten gebeuren
 * door een subclass van AsyncTask.
 *
 * @param id   lamp id
 * @param data JSON data-object
 */
private void write(String id, JSONObject data) {
    try {
        URL url = new URL(BASE_URL + "/lights/" + id + "/state/");
        LightWriter w = new LightWriter(data);
        w.execute(url);
    } catch (IOException e) {
        //TODO: nette foutafhandeling
    }
}

/**
 * LightWriter is van AsyncTask afgeleid, en verzorgt de communicatie met de Bridge
 * voor één instantie van Light. Dit gebeurt op een andere thread dan de UI-thread.
 */
private class LightWriter extends AsyncTask<URL, Void, String> {

    private final JSONObject data;

    public LightWriter(JSONObject data) {
        this.data = data;
    }

    @Override
    protected String doInBackground(URL... params) {
        try {
            // Bouw de HTTP-connectie op en bereid een HTTP PUT request voor.
            HttpURLConnection c = (HttpURLConnection) params[0].openConnection();
            c.setRequestMethod("PUT");
            c.setDoOutput(true);
            c.connect();

            // Schrijf de JSON data in de request body.
            DataOutputStream d = new DataOutputStream(c.getOutputStream());
            d.writeBytes(data.toString());
            Log.d(TAG, data.toString());

            // Lees het resultaat dat de Bridge retourneert.
            BufferedReader b = new BufferedReader(new InputStreamReader(c.getInputStream()));
            String r = b.readLine();
            Log.d(TAG, r);
            d.close();
            c.disconnect();
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
        }

        return null;
    }

    @Override
    protected void onPostExecute(String response) {

    }

}

`

首先,從服務器獲取數據后,您必須更新列表。 然后調用下面提到的方法。

notifyDataSetChanged()

在您的適配器上

您放置了太多的notifyDataSetChanged。 僅將其放在更改列表的位置。 設置適配器一次后,無需再次設置適配器,這就是為什么調用notifyDataSetChanged的原因。 我假設onLightAvailable是您在獲取數據后設置數據的方法,因此它應如下所示:

@Override
public void onLightAvailable(Light item) {
    list.add(item);

    //listView.setAdapter(adapter); only once in the whole app, otherwise notify 
    adapter.notifyDataSetChanged();
}

刪除所有其他adapter.notifyDataSetChanged(); 並且如果您已經在整個應用程序中為該列表設置了適配器,則也應該刪除此方法中的設置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM