Je travaille sur une application d'actualités simple. J'ai besoin de récupérer les données d'un serveur distant au format JSON, puis de les mettre en vue. J'utilise TabLayout et recyclerView pour afficher les catégories de données et Volley pour la requête sans API ici.
Le TabLayout est défini automatiquement en fonction des données de JSON où j'extrait le titre des onglets et le contenu de chaque onglet est affiché sur recyclerView (Titre de l'article , image, contenu, liens ...) et rendu à l'intérieur d'un fragment
J'ai passé plusieurs heures à essayer de le déboguer sans succès., mais quoi que je fasse, aucune donnée n'est affichée. Je ne sais pas ce que je fais de mal.
Je sais que ce n'est pas le bon endroit pour demander de telles choses, mais je suis un peu désespéré et j'aurais besoin d'un développeur expérimenté. problème.
Comment ça marche:
Activity lance BaseArticleFragment qui appelle une méthode qui charge les catégories de contenu et lie les données aux vues:
public static ArrayList<Category> parseCategories(JSONObject jsonObject) { ArrayList<Category> categoryArrayList = new ArrayList<>(); try { JSONArray categories = jsonObject.getJSONArray("categories"); Category all = new Category(); all.setTid("0"); all.setName(ApplicationController.getInstance().getString(R.string.tab_all)); categoryArrayList.add(all); for (int i = 0; i < categories.length(); i++) { JSONObject catObject = categories.getJSONObject(i); Category category = new Category(); category.setTid(catObject.getString("tid")); category.setName(catObject.getString("name")); categoryArrayList.add(category); } return categoryArrayList; } catch (JSONException e) { e.printStackTrace(); return null; } }
5 Réponses :
Vérifiez simplement si vous avez défini LayoutManager pour recyclerView
recyclerView.setLayoutManager(new LinearLayoutManager(MyActivity.this));
Pouvons-nous également avoir votre code et vos données JSON? Puisque nous ne pouvons pas lire ce que vous pensez ou sur votre ordinateur ... Veuillez apporter quelques modifications à votre message, ajouter du code et des données JSON afin que nous puissions vous aider.
Vous avez oublié d'ajouter cette chose à la fin de la méthode "load":
Volley.newRequestQueue (this) .add (jsonRequest);
Essayez de ajoutez-le ...
Au lieu d'utiliser new RequestQueue
, veuillez utiliser RequestQueue jsonQueue = new RequestQueue
Comme ceci:
RequestQueue requestQueue = Volley.newRequestQueue(this); String url = "https://someurl.com/api"; JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(url, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { JSONArray ja = new JSONArray(response); for(int i = 0; i < ja.length(); i++) { JSONObject jo = ja.get(i); String name = jo.getString("name"); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.e("LOG", error.toString()); } }); requestQueue.add(jsonObjectRequest);
Quelque chose ne fonctionne pas, je ne peux obtenir l'erreur que du snack-bar,
@esQmo_ Erreur sur le Snackbar? Je vois que vous travaillez dans le fragment, en fragment, au lieu de activity.this, veuillez utiliser getActivity ()
Oui je l'ai modifié, bien que l'EDI avertisse qu'il pourrait être nul
Mais c'est essentiellement ce que je fais, j'ai une classe ApplicationController
Non j'ai un écran blanc et toujours le message du snack, donc erreur de Volley je suppose?
Ohh, c'est un snack-bar, il a besoin de 'View', pas de contexte comme premier paramètre, veuillez utiliser findViewById (R.id.yourLayoutId); et essayez à nouveau
Oh, le snack-bar que j'utilise pour afficher un message lorsque quelque chose ne va pas, aucun article ne peut être chargé et il s'affiche bien avec ce message
@esQmo_ Je pense que quelque chose ne va pas dans la méthode onResponse. essayez d'utiliser JSONArray ja = response.getJsonArray ();
Que doit-il faire?
Convertit votre JSON d'url en JSONArray
Le problème peut être que je suis confronté à une erreur TimeOut
@esQmo_ J'ai à nouveau édité mon code, ce code obtient l'objet JSON (par exemple, nom, je veux dire sujet 1) en chaîne, vous pouvez alors utiliser cette chaîne quand et où vous voulez ...
En passant, une telle demande fonctionne. Mais j'ajoute la réponse aux catégories, qui est un objet BaseAarticleFragment (protected static ArrayList
@esQmo_ Vous l'ajoutez donc à votre arraylist personnalisé, dites-vous?
Oui, pourriez-vous regarder tout mon projet? Pour mieux comprendre
Essayez ceci @esQmo_,
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/name" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/tid" /> </LinearLayout>
Voici la classe d'adaptateur
public class ExampleAdpater extends RecyclerView.Adapter<ExampleAdpater.ExampleViewHolder>{ public ArrayList<HashMap<String,String>> arraylist; public Context context; public ExampleAdpater(ArrayList<HashMap<String, String>> arraylist, Context context) { this.arraylist= arraylist; this.context = context; } @NonNull @Override public ExampleViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.textLayout,viewGroup,false); return new ExampleViewHolder(view); } @Override public void onBindViewHolder(@NonNull ExampleViewHolder viewHolder, int i) { HashMap<String,String> hashMap = arraylist.get(i); viewHolder.name.setText(hashMap.get("name")); viewHolder.tid.setText(hashMap.get("tid")); } @Override public int getItemCount() { return arraylist.size(); } public class ExampleViewHolder extends RecyclerView.ViewHolder{ TextView name,tid; public ExampleViewHolder(@NonNull View itemView) { super(itemView); name = itemView.findViewById(R.id.name); tid = itemView.findViewById(R.id.tid); name.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(v.getContext(), ""+name.getText().toString(), Toast.LENGTH_SHORT).show(); } }); } } }
textLayout.xml
StringRequest stringRequest = new StringRequest(url , new Response.Listener<String>() { @Override public void onResponse(String response) { try { JSONArray jsonArray = new JSONArray(response); ArrayList<Hashmap<String,String>> arraylist = new ArrayList<>(); for (int i = 0; i < jsonArray.length(); i++) { HashMap<String, String> hashMap = new HashMap<>(); String name = jsonArray.getJSONObject(i).getString("name"); String tid = jsonArray.getJSONObject(i).getString("tid"); hashMap.put("name", name); hashMap.put("tid ", tid ); arraylist.add(hashMap); Log.e("response",name + "\n" + tid); } attachAdapter(arraylist); } catch (JSONException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { } }); RequestQueue queue = Volley.newRequestQueue(this); queue.add(stringRequest); //setting adapter data to the RecyclerView private void attachAdapter(ArrayList<HashMap<String, String>> arrayList) { ExampleAdapter adapter = new ExampleAdapter(arrayList,this); recyclerView.setHasFixedSize(true); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(adapter); adapter.notifyDataSetChanged(); } }
Cela fonctionne, mais rappelez-vous: j'ajoute la réponse aux catégories qui est un objet BaseArticleFragment (protégé statique ArrayList
Comme j'ai essayé de l'expliquer dans ma question, aucune donnée n'est affichée sur les vues. L'activité est vide et j'obtiens une erreur de volley expirée
Avez-vous vérifié en mettant toute ma réponse? Je veux dire que ça marche bien pour moi quand j'utilise la volée de cette façon
Mon approche est assez différente. J'ai la même chose sur ma méthode parseCategories ()
D'accord, je vais vérifier @esQmo_
nous pouvons le faire facilement en utilisant Hashmap @esQmo_. Je peux modifier la réponse pour vous en utilisant le concept HashMap.
J'utilise un ensemble quelque part. Voulez-vous examiner l'ensemble du projet?
Bien sûr @esQmo_ je vais examiner cela
continuons cette discussion dans le chat
Comme vous obtenez une erreur de délai d'expiration, vous pouvez modifier la valeur du délai d'expiration afin qu'il soit prêt à attendre plus longtemps.
Essayez quelque chose comme ceci:
requestQueue.add(jsonObjectRequest);
où MY_SOCKET_TIMEOUT_MS est la durée (en millisecondes) que vous souhaitez attendre avant un délai d'expiration. Commencez par 5000 (5 secondes) et jouez avec.
Faites-le avant
jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy( MY_SOCKET_TIMEOUT_MS, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
J'ai essayé d'ajouter les lignes et de jouer avec la valeur, cela n'a pas fonctionné. Le message d'erreur apparaît dès le lancement de l'activité
Vous pouvez essayer de le déplacer vers onAttach car cela se produit plus tôt, mais vous ne savez pas si cela aidera
Avez-vous vérifié que vous obtenez une réponse positive et non une erreur?
Il n'y a pas de code d'erreur dans le journal, mais le snack-bar de onErrorResponse (VolleyError vError) s'est déclenché
Dans ce cas, vérifiez "volleyError" pour voir quel code d'erreur est renvoyé
Aucun code d'erreur repéré là-bas
C'est étrange. S'il entre le code de réponse d'erreur, il doit y avoir quelque chose dans vError qui indique ce que c'est. Essayez de chercher ici: stackoverflow.com/questions/24700582/handle-volley-error et ici: stackoverflow.com/questions/21867929/... pour des exemples sur la façon d'identifier exactement de quel type d'erreur il s'agit.
Ou devrais-je l'imprimer sur stacktrace?
Aussi une bonne idée. Et ajoutez-le en tant que modification à la question.
J'ai suivi la recommandation de la question suggérée et j'obtiens une erreur de délai d'expiration