我正在为飞利浦色调灯创建一款应用。我从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);
} Bridge类:
/**
* 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) {
}
}
`
答案 0 :(得分:0)
首先,您必须在从服务器获取数据后更新列表。 并调用下面提到的方法。
notifyDataSetChanged()
适配器上的
答案 1 :(得分:0)
你放了太多的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();如果你已经在该应用程序的整个应用程序中的任何位置设置了适配器,则应该删除在此方法中设置它。