繁体   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