Je reçois cette erreur.
22/03 11: 41: 20.439 20933-20933/com.androidcss.jsonexample E/RecyclerView: aucun adaptateur attaché; saut de disposition 03-22 11: 41: 20.760 20933-20933/com.androidcss.jsonexample W/art: Before Android 4.1, method int Android.support.v7.widget.ListViewCompat.lookForSelectablePosition ( int, boolean) aurait incorrectement remplacé la méthode package-private dans Android.widget.ListView
MainActivity.Java
package com.androidcss.jsonexample;
import Android.app.ProgressDialog;
import Android.os.AsyncTask;
import Android.support.v7.app.AppCompatActivity;
import Android.os.Bundle;
import Android.support.v7.widget.LinearLayoutManager;
import Android.support.v7.widget.RecyclerView;
import Android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import Java.io.BufferedReader;
import Java.io.IOException;
import Java.io.InputStream;
import Java.io.InputStreamReader;
import Java.net.HttpURLConnection;
import Java.net.MalformedURLException;
import Java.net.URL;
import Java.util.ArrayList;
import Java.util.List;
public class MainActivity extends AppCompatActivity {
// CONNECTION_TIMEOUT and READ_TIMEOUT are in milliseconds
public static final int CONNECTION_TIMEOUT = 10000;
public static final int READ_TIMEOUT = 15000;
private RecyclerView mRVFishPrice;
private AdapterFish mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Make call to AsyncTask
new AsyncLogin().execute();
}
private class AsyncLogin extends AsyncTask<String, String, String> {
ProgressDialog pdLoading = new ProgressDialog(MainActivity.this);
HttpURLConnection conn;
URL url = null;
@Override
protected void onPreExecute() {
super.onPreExecute();
//this method will be running on UI thread
pdLoading.setMessage("\tLoading...");
pdLoading.setCancelable(false);
pdLoading.show();
}
@Override
protected String doInBackground(String... params) {
try {
// Enter URL address where your json file resides
// Even you can make call to php file which returns json data
url = new URL("https://newsapi.org/v1/articles?source=the-next-web&sortBy=latest&apiKey=bdba5de1b490495796a1595f77ed3f37");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return e.toString();
}
try {
// Setup HttpURLConnection class to send and receive data from php and mysql
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(READ_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("GET");
// setDoOutput to true as we recieve data from json file
conn.setDoOutput(true);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return e1.toString();
}
try {
int response_code = conn.getResponseCode();
// Check if successful connection made
if (response_code == HttpURLConnection.HTTP_OK) {
// Read data sent from server
InputStream input = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
// Pass data to onPostExecute method
return (result.toString());
} else {
return ("unsuccessful");
}
} catch (IOException e) {
e.printStackTrace();
return e.toString();
} finally {
conn.disconnect();
}
}
@Override
protected void onPostExecute(String result) {
//this method will be running on UI thread
pdLoading.dismiss();
List<Item> data=new ArrayList<>();
pdLoading.dismiss();
try {
JSONObject object= new JSONObject(result);
JSONArray array = object.getJSONArray("articles");
// Extract data from json and store into ArrayList as class objects
for(int i=0;i<array.length();i++){
JSONObject json_data = array.getJSONObject(i);
Item item= new Item();
item.name= json_data.getString("title");
data.add(item);
}
// Setup and Handover data to recyclerview
mRVFishPrice = (RecyclerView)findViewById(R.id.fishPriceList);
mAdapter = new AdapterFish(MainActivity.this, data);
mRVFishPrice.setAdapter(mAdapter);
mRVFishPrice.setLayoutManager(new LinearLayoutManager(MainActivity.this));
} catch (JSONException e) {
Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
}
}
}
AdapterFish.Java
package com.androidcss.jsonexample;
import Android.content.Context;
import Android.support.v4.content.ContextCompat;
import Android.support.v7.widget.RecyclerView;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.TextView;
import com.bumptech.glide.Glide;
import Java.util.Collections;
import Java.util.List;
public class AdapterFish extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private LayoutInflater inflater;
List<Item> data= Collections.emptyList();
Item current;
int currentPos=0;
// create constructor to innitilize context and data sent from MainActivity
public AdapterFish(Context context, List<Item> data){
this.context=context;
inflater= LayoutInflater.from(context);
this.data=data;
}
// Inflate the layout when viewholder created
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view=inflater.inflate(R.layout.card, parent,false);
MyHolder holder=new MyHolder(view);
return holder;
}
// Bind data
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
// Get current position of item in recyclerview to bind data and assign values from list
MyHolder myHolder= (MyHolder) holder;
Item current=data.get(position);
myHolder.name.setText(current.getName());
// load image into imageview using glide
/*Glide.with(context).load("http://192.168.1.7/test/images/" + current.fishImage)
.placeholder(R.drawable.ic_img_error)
.error(R.drawable.ic_img_error)
.into(myHolder.ivFish);*/
}
// return total item from List
@Override
public int getItemCount() {
return data.size();
}
class MyHolder extends RecyclerView.ViewHolder{
TextView name;
// create constructor to get widget reference
public MyHolder(View itemView) {
super(itemView);
name = (TextView)itemView.findViewById(R.id.name);
}
}
}
Item.Java
package com.androidcss.jsonexample;
public class Item {
String name;
public String getName() {
return name;
}
}
Vous devez setLayoutManager
avant setAdapter
.
Vous initialisez le RecyclerView
dans AsynTask
, cela signifie que votre ReyclerView
n'est pas prêt lorsque la vue est créée.
Apportez les modifications suivantes.
//make list as global variable
private List<Item> data;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//view should be initialized in UI thread
data=new ArrayList<>();
mRVFishPrice = (RecyclerView)findViewById(R.id.fishPriceList);
mAdapter = new AdapterFish(MainActivity.this, data);
mRVFishPrice.setLayoutManager(new LinearLayoutManager(MainActivity.this));
mRVFishPrice.setAdapter(mAdapter);
//Make call to AsyncTask
new AsyncLogin().execute();
}
Puis dans votre onPostExecute
remplacer -
mRVFishPrice = (RecyclerView)findViewById(R.id.fishPriceList);
mAdapter = new AdapterFish(MainActivity.this, data);
mRVFishPrice.setAdapter(mAdapter);
mRVFishPrice.setLayoutManager(new LinearLayoutManager(MainActivity.this));
avec
mAdapter.notifyDatasetChanged();
et assurez-vous également de supprimer le List<Item> data
de postexecute et le rendre global
Et veuillez utiliser Volley pour effectuer des appels d'API au lieu d'implémenter une tâche d'arrière-plan personnalisée. Volley gère les appels API de manière asynchrone sans gâcher votre code réel.
J'ai fait face au même problème. Le problème était dans Layout. Vous devez d'abord vérifier que si vos vues et mises en page sont dans le bon ordre.