Je construis un client android simple pour consommer une API REST que j'ai faite et installée sur mon serveur. Je réussis à atteindre le point de terminaison pertinent avec une requête GET et récupérer les données que je veux. Si j'appuie sur le bouton envoyer un message, je peux ajouter un nouveau message à la liste. Je ne peux pas sembler rafraîchir cette liste, donc je dois me déconnecter et à nouveau pour voir les changements reflétés.Cant actualiser listview dans android - notifyDatSetChanged() ne fait rien
Voici le code pour les classes appropriées:
PostsActivity (UI):
package com.bitcrunchy.gez.project2;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
* Created by gerron on 05/03/16.
*/
public class PostsActivity extends AppCompatActivity {
ListView lvPosts;
public Button postButton;
private PostAdapter adapter;
private ArrayList<Post> postList;
public Button getSubmitPostButton() {
return postButton;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_posts);
Intent intent = getIntent();
final String jwt = intent.getStringExtra("jwt");
lvPosts = (ListView) findViewById(R.id.posts_list);
postButton = (Button) findViewById(R.id.button);
postButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sendPost("test post!", "test", null, null, null,
getApplicationContext(), jwt);
adapter.notifyDataSetChanged();
}
});
lvPosts.setItemsCanFocus(false);
postList = new ArrayList<>();
//get posts from hitting the api end point and parsing the json HAL response
this.getPosts(this.getApplicationContext(), jwt);
}
public void getPosts(final Context context, final String jwt) {
RequestQueue queue = Volley.newRequestQueue(this.getApplicationContext());
final int loggedInUser = 25;
StringRequest sr = new StringRequest(Request.Method.GET, "http://www.project.com/api/users/" + loggedInUser + "/posts", new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
JSONObject hal = new JSONObject(response);
if (hal.has("_embedded")) {
JSONObject embedded = new JSONObject(hal.getString("_embedded"));
if (embedded.has("posts")) {
JSONArray posts = new JSONArray(embedded.getString("posts"));
for (int i = 0; i < posts.length(); i++) {
JSONObject post = new JSONObject(posts.getString(i));
PostFactory postFactory = new PostFactory();
postList.add(postFactory.getPost(post));
}
adapter = new PostAdapter(context.getApplicationContext(), postList, postButton);
lvPosts.setAdapter(adapter);
}
if (hal.has("err-msg")) {
System.out.println("ERROR : ".concat(hal.getString("err-msg")));
}
}
} catch (JSONException e) {
System.out.println("JSON EXCEPTION : " + e.getStackTrace().toString());
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
System.out.println("VOLLEY ERROR : " + error);
}
}) {
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/x-www-form-urlencoded");
params.put("Authorization", "Bearer " + jwt);
return params;
}
};
queue.add(sr);
}
public void sendPost(final String text, final String url, String eventId, String groupId,
String attachmentId, final Context context, final String jwt) {
final String event = eventId;
final String attachment = attachmentId;
RequestQueue queue = Volley.newRequestQueue(this.getApplicationContext());
final int loggedInUser = 25;
StringRequest sr = new StringRequest(Request.Method.POST, "http://www.project.com/api/users/" + loggedInUser + "/posts", new Response.Listener<String>() {
@Override
public void onResponse(String response) {
getPosts(context.getApplicationContext(), jwt);
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
System.out.println("VOLLEY ERROR : " + error);
}
}) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("text", text);
if (url != null) {
params.put("url", url);
}
if (event != null) {
params.put("event-id", event);
}
if (attachment != null) {
params.put("attachment-id", attachment);
}
return params;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/x-www-form-urlencoded");
params.put("Authorization", "Bearer " + jwt);
return params;
}
};
queue.add(sr);
}
}
PostAdapter:
package com.bitcrunchy.gez.project;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
/**
* Created by gerron on 12/03/16.
*/
public class PostAdapter extends BaseAdapter {
private Context mContext;
private List<Post> posts ;
private Button btn;
public PostAdapter(Context mContext, List<Post> posts, Button btn) {
this.mContext = mContext;
this.posts = posts;
BinaryImageResolver resolver = new BinaryImageResolver();
}
@Override
public int getCount() {
return posts.size();
}
@Override
public Object getItem(int position) {
return posts.get(position);
}
public void updatePostsList() {
notifyDataSetChanged();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return posts.get(position).render(mContext);
}
}
SimplePost:
package com.bitcrunchy.gez.project;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Created by gerron on 04/03/16.
*/
public class SimplePost extends AbstractPost {
public SimplePost(JSONObject postJSON) {
super(postJSON);
}
public View render(Context mContext) {
View v = View.inflate(mContext, R.layout.simple_post_row_layout, null);
//get views
ImageView profileImage = (ImageView) v.findViewById(R.id.profile_pic);
TextView username = (TextView) v.findViewById(R.id.username);
TextView timeOfPost = (TextView) v.findViewById(R.id.time_of_post);
TextView dateOfPost = (TextView) v.findViewById(R.id.date_of_post);
TextView postText = (TextView) v.findViewById(R.id.post_text);
TextView urlView = (TextView) v.findViewById(R.id.url);
//set view values
Resources res = mContext.getResources();
Drawable drawable = res.getDrawable(R.drawable.profile_image_dummy);
profileImage.setImageBitmap(bitmap);
username.setText("user 0");
timeOfPost.setText(date);
dateOfPost.setText(time);
postText.setText(text);
urlView.setText(url);
v.setTag(id);
return v;
}
public void generateFromJSONPost() {
try {
JSONObject links = new JSONObject(post.getString("_links"));
JSONObject sender = new JSONObject(links.getString("sender"));
getLastLeafFromUrl(sender.getString("href"));
} catch (JSONException e) {
e.printStackTrace();
}
}
public void populateValuesFromLinks() {
generateIdFromJSONPost();
}
}
AbstractPost:
package com.bitcrunchy.gez.project;
import android.content.Context;
import android.graphics.Bitmap;
import android.view.View;
import android.widget.AdapterView;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
/**
* Created by gerron on 16/03/16.
*/
abstract class AbstractPost implements Post {
JSONObject post;
int id;
String text;
String url;
String time;
String date;
int senderId;
Bitmap bitmap;
Map<String,String> dateTime;
public AbstractPost(JSONObject postJSON) {
try {
post = postJSON;
id = Integer.parseInt(post.getString("id"));
text = post.getString("text");
if (post.getString("url") != "null") {
url = post.getString("url");
} else {
url = " ";
}
dateTime = MySqlTimeConverter.splitIntoDateAndTime(post.getString("time_of_post"));
date = dateTime.keySet().toArray()[0].toString();
time = dateTime.get(date);
populateValuesFromLinks();
generateIdFromJSONPost();
BinaryImageResolver resolver = new BinaryImageResolver();
//load from api instead
byte[] decoded = resolver.decodeBase64("iVBORw0KGgoAAAANSUhEUgAAAMwAAADMCAMAAAAI\\/LzAAAAAkFBMVEX\\/\\/\\/8AAAD8\\/Pz5+fn09PTu7u7x8fH29vbs7Ozj4+MfHx8YGBjp6ekaGhoiIiI+Pj4rKyvd3d1ERES3t7doaGgzMzM6OjrV1dUvLy9eXl4oKCgLCwtQUFDZ2dnR0dHHx8eAgICrq6tgYGBKSkqNjY2jo6N0dHS0tLRUVFSSkpK+vr6cnJyHh4dtbW2pqal3d3ezd5XVAAAPCUlEQVR4nO1diXKjuhIdJBazL0bsBsxidvv\\/\\/+5JgPMyk3hJEE5uFadu1a2a8YCO1DpqtbrFnz8bNmzYsGHDhg0bNmzYsGHDhg0bNmzYsGHDhtcBvMNPt2UBoMByiiKaB3fEwRRFheMF+B\\/jBCCvHOK26lK7zh3kGR7+Dzl5naXNcZ+4Iif8NxgByIkJplE7aihrHkKObll5bumEVKCGTIiiU3NMzN9PSNiZbXOKkBY4VlT7BHVEkGOM\\/7N0ZKhyYNl95Srs7+UDeDHpayfwrNrPMr\\/OLcczNDlkJoSqFhjIweNk4b+QVC+\\/7E0O\\/nSrPwMQxKSLVM2JMjvzc8cIAs\\/Js1NalOVxvz+WZZGe7MjxNEnSPExJR4EcOn1r\\/rrhAbxZpUhy6sz2c4THJrs0VeKaWL84nmUFgWVZntsp4iGumjTLDVXyHF1HGqPaZfyrhgewZjk4QT4ykRy7LxNT+VSEAYACr5jJuRh0WQ6QgwxZ8xv399ARxCozUG3btSMHdtcelEeLCRA4sy1PHiMbCNORo9JkX9TY+4BiZUuOP9iRYdRdLD49BVjFPfsGkW9DZqzS\\/HmpBrukx6MyZJFnXSqT\\/5K5YPlr+1xWDS+QmWEv\\/rCtCWYZBdjAIiPv228sG0BQkiIKVcPQsLLFP2lrgI9tQ7eHOgj69rv9CpWk8xgJewdy1O5+zNTwsCDPHzLkXZIlrcB90qNQC7RQ7t0fGhw2ST3LtnPDrpZaO1Tak4TpyKHd8j8wOIBrfa8efKQ3BwrvF8QuZyRNYvSj8nI2QDlaKBsiNdvTeTnYtQMja1LodeKL2QCzCKzB1r3GpKanUDx7oSSFzCV+qUZDMzUibGIRVZvAlluHsiQz9is1WnAvAZ4uht1ydB\\/MJqeJTfIyNtA9af5Qyyn9DhQOBd73qIyfCLQf\\/TlgkgUZVuRmDdkBu3NA2OT7l7ARYt\\/wbUsvVxId5aiHKvY8X2FpgjsEmItzXms5ALtKZ2QZW9rqbMDhomW2pVUrLm1cKxE22doKDbCOERurVu01odXD9dkApTdqzOW4W\\/MteGyqkc1pVV9gV2qRHXnl6u6TcjRCOWRWEcwZ\\/F7P7Trs1ncFgXJmMJvgTHlV\\/j\\/YNnLs2iiUtV7wHrtGDmXGqfh1Hg\\/cAWU+uhzujAtguccxZCDw3MNgAZZNMm3qlURgV+DdPrrraEDzmKaleX\\/xhsq+vxTtI1uFsU8E+rKKTbNtkOPFsr0z7oKbqbIs31\\/ugNlrYRhqxSOpYltEROC4gqHBGE+YSD3emZHQ9UPHspwwSu7YhtIzqqZpMvOQDV8xYcg49H1OIPae7weXew1QCk23LMImva0RQiKrgUbYeI9WXqBcyOnByaRtaEKl55lT3+ty2Foe4WLphnT7d7iB2ggJr4kPXgqSGpPRzrQNzbVRVqPynuxzjaxPZBymufV+4CJ5JhM67aMu588BZpPHdIeG79Q6M9K7Vn6wjJEKhlTf6nT2rEoTF0llukceHlBSYmg9Ve8JurqVWdbdqQgSGc1c9MC5tRhxRThzwWT6h8svjC1MRqKqAbtC82u5u9tBsGWcmYvjee4NMrtLOFEhZIZHkwaTL8nQXCg6HTCx8OzP7y39+Ed7xtEnLpjMrYVbuYTSBLw3th+TAWaEyXgUN9FKavhRcL5v4Xhk0MzFCdBNM0vfkXmmw4WjitkM5jeafaOZueUj273\\/KxAbxszFkaJbUsF28kwF7\\/Nvat57HAZMBlW0hoZrjBrL8qM3i7bsTFwQk97ScNhq8sRFDYPqGSeSHeX5zjL8JYA4130nuz9jMISz5Dkjl4BpbzUTiD4zUlFDxj489X7TxmSMhM5aw5ZqXQcPBwY77YOKCBcvvDOz2YqRsYmFDBMcnwsksOOsKahs03BfIl\\/P3ccmwbaWihDyZOeO+ADxRNxHshQ+ucMHZo5\\/rVPx0IREy2upeGYR5ip99HPP9wwcxqcx+yR9+vyA68jvqajzrg\\/q\\/I7n+B583A12F9+3CMHcX7J0\\/3zkBcajOlOQAHCo9Ro9sbxNv8bb5sdnzgK3+1JKhkLUWacgAUKFoih46BKuCuGMyagU2rDrjdrSHzrr6yKx6DhoB9upET1v4nsQyZYzWmxnsNWtyGhWi8U9B+wEYTs7LtUztgzy3KHmGX0TuEvx0CzuUqUPIr2+tTt5FYDpYzLPSupNHGpUe6eXBGTvYUe2zyhe9hCQID0KnnLVV4VwxpPmtvv6HOBezfPgNYeld9uRaJhMuawdWEZyC702Y+IzgIND3LllCrA7aRGKqIcUvw6RKEC9bO6KtRcFNFy8peBGBVjUq8DUUa72P7xkErAk5CQvsnfgGroVPgjLvARCSxLwn9uI3ABMJMsKFyoiFYCEbNAWOTTCXrV0eVF\\/UAIYN2jdkgWPLVXL0SgFRpbhgEjYYMns5TspRwblE4XvwbSWLjR8oVlIfy68tTJEcu60yEnk+sDyrN9BZvSbl5HRLC\\/64W3mBDFbugngUkym\\/hVkFBKkzRaS0Y1fQmagQuZ3mBmlkcl\\/BRlxOZlec34LmeVqVmAy315nSLHcThFdN8ZwTUXhWPjtau1xnVm0GeEbyTHQl2MzAEB2Jx6Sqmz69ESqT\\/OottO+6I5tbH6P03iucVmSEMB2quMFX3NnSHGzuyc12panMn8jDJwoO\\/Vd64pfLWY09aXujHCUHU\\/9iqMJeDPpI6SFzG2EcoCitP1aKbBrkOOzJV4zTGSEnt7P4DE5VEV+h8Zf0Ptz+3TtOYhJ95RLtokwljzEPBechby5bzLpWSojkF0cn6uehWSnuez0DBw8Az21JYJK3GXOh9YGej30fdE0RdGndqR\\/5BrUTbx7TEfYM0u3zX\\/EXEPyYw2BSntB\\/0wTrU7LKokPorLjCBTFJLc3lKf8H1kInSLmHiZrkXNNaVnMW7FVJPkP1l3BrIa\\/WmdYdpccFP6T+QAFrHVtkVnB+38h9cmDvNIdOdXVl0XO+SL0Av1uPgNUqtP7lulDUbmfErkCYEJx1Wfo3b+yivhuTeG4ZmbLAnjCkTEM446pAt5N3zVKO3XPKRQmdNh3\\/js69Vm8kz0whQCWBfBBKweGdL75FiAe30mx1STiF2o2sZLv3\\/WEfEpuTh2YEOlYenQWW5IhpbcUgI0vb21BQ2t+ufoU8ynrN4lTb+Z38x2Wl3DpMbE4yIGUfR7jBVybvVG57MVvFfQD\\/lBmb3eG3KrJU8j8tx4kiT0E14SBlH\\/u0HCVdeVi7+8Y\\/APgadfp1wdln85PcBhjM0uPAeHR0DTjUzeCra6LJOoepP8\\/AOCSVL7qwOETNrAiU2tRPHNEXKuBnH7SJ3xrXIfl9sR9FkB5G2X7k\\/wpbB8kUXNxmFi8yJrsfzwa5dtZxuT0QOOUkE\\/seeZcPrIxyaLsL50yREc0TfqYgCiMme0YAa1SbSFOJzZh\\/+8+HbTjIeDyMy+YWJL2IecbJvN6p9OrcYRmM1ta8c8zWeKYBYsTNP6M4qzJzuziAU4UdwJk3VmT9YTiqTpQmtnSOlGAvKIos9iPvkz0MEn0CfDnUJKYKZ8SmsXp1JftfkrmYxy69ZrAnC1NKlq88T5dqvFqDjgeNFEpCICup0qhPSbucQWx6UCfNVluKB\\/dktKsyRfQEdFqNJrWrid\\/1FJJRuBSRlKD8VlixMjy2x1fTEY9p4avrno\\/gUQwQEwWmZt1H18DyatW5Qt5mJJhMuqb80EnPfcvjIHLN4Qk0WVcZJjbzu7XYA6hKltkaPgjQ+oNZ1DRl3\\/An9+T0bFzA2Iy\\/fOFSUBvYM94aEJSa4r15t0+DK1wDC0k77hYe26sQ2Jo5Wj\\/IW6eHaqhMzZdSdI3OsYKOXXwjUwYnUfXYhoYeofE7NnAxjWtwFBJbG0Ws+We3wfw5dXCuul+Pa4ZZye9Qi1gZniqqHOxFF6pZzY0C45mKHNopG6ngmHoEimzaKYikGoEmRnmJHFgFrM0Uz+6BYfJeY6uhbrTGtPQrKADuMPkULpWNgKxn0yBerqzcBwHPb8WFLN7MkPpFDW8AY51xvl1tIF4ItofVLTJsOOa4ly5gNEHDGkvAUoRYqRX5xy4ZGtIIz3\\/bwglJmO9eXxKQxY16iniECskNrS3+h1olrnTURcA7Gq+uzQJ2wMZJ\\/oponzlhSETxNcHA1b8SozsWUBOVK7KBQ9kMytTnf0TgDJO+uGzeMM6mGVmWCNDFI7hnvBhFT817EY\\/xlvnCiqhIrK54oUjf2OOZK3gZYzYdeOG6TVVDsIU\\/enpbGM+AkvN5Je\\/5H6rMfpjr5cfDmN7esPqYwMPp788gTUgJN4oME8UbS7CbAPMftWKCmEMx605+gTAHcdFerLE9tvgjmhabla0NGiOXDT6Dsa\\/UMYicObirsYGHtIpmLH+ikbut5rmzUps4GRjTPGS2hCu1Kb90yoWzbajJof\\/xpvXglKiKXZC\\/3ZlwO3HtVJrXlWzgy1tjDvqJe2LvIFYjttm9YWX6YJdNUYCJcp2DcxiOnle7V7LT8G20RxEoWdqYDdNF2y\\/Ly7Y4ZPhGt6ipGqCOZ85Z7Sv533i3e4Ub9KG5cezf8YD52GKxq1wPe9jQLGbArXo0b15T4Dc\\/T4+TKV4m\\/WXwF0PiOvzos8tAPJ1gSms6L\\/exK4QDsXoRTPyqXr+sxP\\/ALBiNUydEvzYTfoEUKnmk1o0fC93ZqTizcNyVH62uo1155nDSH51+KoUAO5Q+XOWo9bcT597BQDvXuaeZfSCfLfoyRYByJn7\\/pp+Y5we52m+AlDZv9ExhmZv7oSH1gKFnblv7OCNyuKPPlCDIFanawZciPz0GIs79tYIAchyYnxM\\/bd0W3movperthIEsf3\\/8SAjG3V6bkkWMM8KEE7f0oNQYHlFNOP2nEbG2ykvo6UtLSeCGiDndv77fFhGtvxL05XnY7XHqI7nsmsuvvVXVrPnd+4TKdqvB+DxhM485l\\/IaoAhyR\\/+IvD73\\/qhsz9zZUM3fOTzCQy7qdzdb5oqnwDyYrxvfPRxIP4\\/VMhv9skXv+\\/0Y4C8gud5k9r++CnAYALSrby2L80+NhX+P\\/Uhyrne7BAnbXWcsE\\/ig6ns\\/ntf1LxilGQoEIwS\\/dPt2bBhw4YNGzZs2LBhw4YNGzZs2LBhw4YNG+7jf70oLnsiKBNTAAAAAElFTkSuQmCC");
bitmap = resolver.getBitmapFromBytes(decoded);
bitmap = Bitmap.createScaledBitmap(bitmap, 42, 42, false);
} catch (JSONException e) {
System.out.println("JSON Exception : " + e.getStackTrace().toString());
}
}
public void generateIdFromJSONPost() {
try {
JSONObject links = new JSONObject(post.getString("_links"));
JSONObject sender = new JSONObject(links.getString("sender"));
senderId = getLastLeafFromUrl(sender.getString("href"));
} catch (JSONException e) {
e.printStackTrace();
}
}
public void populateValuesFromLinks() {
generateIdFromJSONPost();
}
public int getLastLeafFromUrl (String senderUrl) {
String[] urlParts = senderUrl.split("/");
return Integer.parseInt(urlParts[urlParts.length-1]);
}
@Override
public String toString() {
return "{id: " + id + ", text: " + text + ", url: " + url + ", time-of-post: " + time.toString() + "}";
}
public View render(Context mContext) {
//do nothing, implement in subclasses.
return null;
};
}
J'ai vu des gens suggérant que j'ai besoin appeler onClickListener()
sur le bouton de l'intérieur méthode getView()
adaptateur de poste. Évidemment postAdapter n'a pas un bouton, qui appartient à l'interface utilisateur, donc j'ai essayé de passer une référence au bouton dans le PostAdapter afin que onClickListener
pour le bouton peut être défini int getView()
. Cela ne fait rien non plus. Ma liste est définitivement mise à jour mais je ne peux pas l'obtenir pour actualiser les changements.
S'il vous plaît offrir des conseils que vous pouvez :)
quelqu'un peut-il me dire si si je me trompe de penser que si je dois mettre en œuvre un bouton click listener dans PostAdapter je peux juste passer la référence en tant qu'argument au constructeur? Pour autant que je puisse dire que cela ne devrait pas être un problème, mais ça ne marche pas. – gezinspace