J'implémente un chargement de données sans fin pour un RecyclerView. Lorsque le logiciel détecte que le dernier élément va être affiché, il télécharge les nouveaux éléments et appelle la fonction loadMoreData()
mais le nouvel ensemble de données ne s'affiche pas.
Quand j’ai appelé notifyDataSetChanged()
, il ne se passait rien.
Je n'ai qu'une solution qui est d'actualiser la vue est de configurer à nouveau l'adaptateur, mais le problème est que recyclerview revient à la première position, puis à nouveau recyclerview défilant de la première position à la dernière.
RecyclerViewActivity.Java
RecyclerView rv;
DatabaseHelpr databaseHelpr;
RVAdapter adapter;
LocationFinder locationfinder;
Location currentLocation;
ArrayList<ServiceModel> childList, list;
private int MainService_ID, city_id;
String url2;
ActionBar actionBar;
JSONArray items = null;
Utility utility;
Double lat, longi;
LinearLayoutManager llm;
int counter=0;
ProgressBar progressBar;
private static final String TAG_ITEMS = "items";
private static final String TAG_LOCALITY = "Locality";
private static final String TAG_BUSINESS_ID = "Business_Id";
private static final String TAG_LONGITUDE = "Longitude";
private static final String TAG_BUSINESS_NAME = "Business_Name";
private static final String TAG_LATITUDE = "Latitude";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.recyclerview_activity);
list = new ArrayList<>();
utility = new Utility(this);
llm = new LinearLayoutManager(this);
Bundle bundle=getIntent().getExtras();
MainService_ID=bundle.getInt("service_id");
String mainService_Name = bundle.getString("service_name");
city_id = bundle.getInt("city_id");
lat= bundle.getDouble("lat");
longi=bundle.getDouble("longi");
rv=(RecyclerView)findViewById(R.id.rv);
rv.setLayoutManager(llm);
actionBar = getSupportActionBar();
assert actionBar != null;
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle(mainService_Name);
//Here city_id = 8, lat = 18.552954, longi = 73.897200, counter=0, MainService_ID = 5
String url="https://servicedata2-dot-indiacomapi.appspot.com/_ah/api/servicedata/v1/ServiceData?city_id=";
url2 =url+city_id+"&lat="+lat+"&lng="+longi+"&roll="+counter+"&service_id="+MainService_ID;
AsyncHttpClient client = new AsyncHttpClient();
progressBar=(ProgressBar) findViewById(R.id.progressBar1);
progressBar.setVisibility(View.VISIBLE);
client.get(url2, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
// called when response HTTP status is "200 OK"
String s = new String(response);
try {
JSONObject jsonObj = new JSONObject(s);
// Getting JSON Array node
items = jsonObj.getJSONArray(TAG_ITEMS);
// looping through All Contacts
for (int i = 0; i < items.length(); i++) {
JSONObject c = items.getJSONObject(i);
String locality = c.getString(TAG_LOCALITY);
String business_Id = c.getString(TAG_BUSINESS_ID);
String longitude = c.getString(TAG_LONGITUDE);
String latitude = c.getString(TAG_LATITUDE);
String business_Name = c.getString(TAG_BUSINESS_NAME);
locationfinder = new LocationFinder(RecyclerViewActivity.this);
// check if GPS enabled
if (locationfinder.canGetLocation()) {
double lat = locationfinder.getLatitude();
double longi = locationfinder.getLongitude();
currentLocation = new Location("");
currentLocation.setLatitude(lat);
currentLocation.setLongitude(longi);
} else {
locationfinder.showSettingsAlert();
}
Location savedLocation = new Location("databaseLocation");
savedLocation.setLatitude(Double.parseDouble(latitude));
savedLocation.setLongitude(Double.parseDouble(longitude));
Double difference = currentLocation.distanceTo(savedLocation) * (0.001);
difference = Double.parseDouble(new DecimalFormat("##.##").format(difference));
String newDifference = String.valueOf(difference) + " km";
ServiceModel serviceModel = new ServiceModel(business_Id, business_Name, newDifference, locality);
list.add(serviceModel);
}
} catch (JSONException e) {
e.printStackTrace();
}
progressBar.setVisibility(View.GONE);
adapter = new RVAdapter(RecyclerViewActivity.this, list);
rv.setAdapter(adapter);
rv.addOnScrollListener(new EndlessRecyclerOnScrollListener(llm) {
@Override
public void onLoadMore(int current_page) {
// counter= counter+1;
loadMoreData();
}
});
}
@Override
public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
// called when response HTTP status is "4XX" (eg. 401, 403, 404)
//Toast.makeText(getApplicationContext(),""+statusCode,Toast.LENGTH_LONG).show();
}
});
}
private void loadMoreData() {
counter= counter+1;
//Here city_id = 8, lat = 18.552954, longi = 73.897200, counter=1, MainService_ID = 5
String url="https://servicedata2-dot-indiacomapi.appspot.com/_ah/api/servicedata/v1/ServiceData?city_id=";
url2 =url+city_id+"&lat="+lat+"&lng="+longi+"&roll="+counter+"&service_id="+MainService_ID;
AsyncHttpClient client = new AsyncHttpClient();
progressBar=(ProgressBar) findViewById(R.id.progressBar1);
progressBar.setVisibility(View.VISIBLE);
client.get(url2, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
// called when response HTTP status is "200 OK"
String s = new String(response);
try {
JSONObject jsonObj = new JSONObject(s);
// Getting JSON Array node
items = jsonObj.getJSONArray(TAG_ITEMS);
// looping through All Contacts
for (int i = 0; i < items.length(); i++) {
JSONObject c = items.getJSONObject(i);
String locality = c.getString(TAG_LOCALITY);
String business_Id = c.getString(TAG_BUSINESS_ID);
String longitude = c.getString(TAG_LONGITUDE);
String latitude = c.getString(TAG_LATITUDE);
String business_Name = c.getString(TAG_BUSINESS_NAME);
locationfinder = new LocationFinder(RecyclerViewActivity.this);
// check if GPS enabled
if (locationfinder.canGetLocation()) {
double lat = locationfinder.getLatitude();
double longi = locationfinder.getLongitude();
currentLocation = new Location("");
currentLocation.setLatitude(lat);
currentLocation.setLongitude(longi);
} else {
locationfinder.showSettingsAlert();
}
Location savedLocation = new Location("databaseLocation");
savedLocation.setLatitude(Double.parseDouble(latitude));
savedLocation.setLongitude(Double.parseDouble(longitude));
Double difference = currentLocation.distanceTo(savedLocation) * (0.001);
difference = Double.parseDouble(new DecimalFormat("##.##").format(difference));
String newDifference = String.valueOf(difference) + " km";
ServiceModel serviceModel = new ServiceModel(business_Id, business_Name, newDifference, locality);
list.add(serviceModel);
}
} catch (JSONException e) {
e.printStackTrace();
}
progressBar.setVisibility(View.GONE);
//adapter = new RVAdapter(RecyclerViewActivity.this, list);
//rv.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
@Override
public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
}
});
Toast.makeText(this, "Net is present", Toast.LENGTH_SHORT).show();
}
}
RVAdapter.Java
public class RVAdapter extends RecyclerView.Adapter<RVAdapter.PersonViewHolder>{
private final LayoutInflater mInflater;
List<ServiceModel> persons ;
private Context mContext;
public RVAdapter(Context context,List<ServiceModel> persons){
this.mInflater = LayoutInflater.from(context);
this.persons = new ArrayList<>(persons);
this.mContext = context;
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
@Override
public PersonViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
PersonViewHolder pvh = new PersonViewHolder(v);
return pvh;
}
@Override
public void onBindViewHolder(PersonViewHolder personViewHolder, int i) {
ServiceModel person = persons.get(i);
personViewHolder.businessName.setOnClickListener(clickListener);
personViewHolder.image_url.setOnClickListener(clickListenerImage);
personViewHolder.businessName.setTag(personViewHolder);
personViewHolder.difference.setTag(personViewHolder);
personViewHolder.business_id.setTag(personViewHolder);
personViewHolder.image_url.setTag(personViewHolder);
personViewHolder.locality.setTag(personViewHolder);
personViewHolder.businessName.setText(Html.fromHtml(person.getBusinessname()));
String firstLetter = String.valueOf(person.getBusinessname().charAt(0));
ColorGenerators generator = ColorGenerators.MATERIAL; // or use DEFAULT
int color = generator.getColor(person.getBusinessname());
TextDrawable drawable = TextDrawable.builder().buildRound(firstLetter, color); // radius in px
personViewHolder.image_url.setImageDrawable(drawable);
personViewHolder.difference.setText(Html.fromHtml(person.getNewDiffer()));
personViewHolder.locality.setText(Html.fromHtml(person.getLocality()));
personViewHolder.bind(person);
}
View.OnClickListener clickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
PersonViewHolder holder = (PersonViewHolder) view.getTag();
int position = holder.getPosition();
ServiceModel person = persons.get(position);
String businessids = person.getBusinessid();
Intent intent = new Intent(mContext, BusinessInfoActivity.class);
intent.putExtra("businessids", businessids);
mContext.startActivity(intent);
}
};
View.OnClickListener clickListenerImage = new View.OnClickListener() {
@Override
public void onClick(View view) {
PersonViewHolder holder = (PersonViewHolder) view.getTag();
int position = holder.getPosition();
ServiceModel person = persons.get(position);
String businessids = person.getBusinessid();
Intent intent = new Intent(mContext, BusinessInfoActivity.class);
intent.putExtra("businessids", businessids);
mContext.startActivity(intent);
}
};
@Override
public int getItemCount() {
return persons.size();
}
public void animateTo(List<ServiceModel> models) {
applyAndAnimateRemovals(models);
applyAndAnimateAdditions(models);
applyAndAnimateMovedItems(models);
}
private void applyAndAnimateRemovals(List<ServiceModel> newModels) {
for (int i = persons.size() - 1; i >= 0; i--) {
final ServiceModel model = persons.get(i);
if (!newModels.contains(model)) {
removeItem(i);
}
}
}
private void applyAndAnimateAdditions(List<ServiceModel> newModels) {
for (int i = 0, count = newModels.size(); i < count; i++) {
final ServiceModel model = newModels.get(i);
if (!persons.contains(model)) {
addItem(i, model);
}
}
}
private void applyAndAnimateMovedItems(List<ServiceModel> newModels) {
for (int toPosition = newModels.size() - 1; toPosition >= 0; toPosition--) {
final ServiceModel model = newModels.get(toPosition);
final int fromPosition = persons.indexOf(model);
if (fromPosition >= 0 && fromPosition != toPosition) {
moveItem(fromPosition, toPosition);
}
}
}
public ServiceModel removeItem(int position) {
final ServiceModel model = persons.remove(position);
notifyItemRemoved(position);
return model;
}
public void addItem(int position, ServiceModel model) {
persons.add(position, model);
notifyItemInserted(position);
}
public void moveItem(int fromPosition, int toPosition) {
final ServiceModel model = persons.remove(fromPosition);
persons.add(toPosition, model);
notifyItemMoved(fromPosition, toPosition);
}
public static class PersonViewHolder extends RecyclerView.ViewHolder {
protected CardView cv;
protected TextView businessName, difference, business_id, locality;
protected ImageView image_url;
public PersonViewHolder(View itemView) {
super(itemView);
cv = (CardView)itemView.findViewById(R.id.cv);
businessName = (TextView)itemView.findViewById(R.id.business_name);
difference = (TextView)itemView.findViewById(R.id.txtDifferenece);
business_id = (TextView)itemView.findViewById(R.id.business_id);
image_url = (ImageView)itemView.findViewById(R.id.thumbnail);
locality= (TextView)itemView.findViewById(R.id.txtLocality);
}
public void bind(ServiceModel model) {
businessName.setText(model.getBusinessname());
}
}
}
S'il vous plaît, aidez-moi, Comment définir notifyDataSetChanged()
sur l'adaptateur. cela ne fonctionne pas dans mon code. J'ai déjà vérifié toutes les réponses qui sont postées sur le stackoverflow.
vous définissez la nouvelle liste sur l'adaptateur RecyclerView, définissez la liste dans l'adaptateur:
créer une méthode setItems(list)
dans l’adaptateur et l’appeler avant notifyDataSetChanged()
et dans l’adaptateur
this.persons = new ArrayList<>(persons);
en setItems
ajoutez cette méthode à l'adaptateur:
public void setItems(List<ServiceModel> persons) {
this.persons = persons;
}
et appelez-le avant notifyDataSetChanged()
comme ceci:
adapter.setItems(list);
adapter.notifyDataSetChanged();
La question est dans ces lignes ..
adapter = new RVAdapter(RecyclerViewActivity.this, list);
rv.setAdapter(adapter);
adapter.notifyDataSetChanged();
Vous initialisez votre adaptateur à chaque fois. Pas besoin de le réinitialiser . Il suffit de mettre à jour votre arraylist
et d'appeler à adapter.notifyDataSetChanged();
le fera fonctionner.
Comme @Beena l'a mentionné, vous créez et configurez un nouvel adaptateur à tout moment, dans votre réponse de réussite.
Une solution serait de créer un adaptateur et de le définir pour la première fois sur la vue Recycler, puis d'appeler une méthode de votre adaptateur onSuceess () de votre rappel d'API.
Dans cette méthode d’adaptateur, ajoutez simplement ces nouvelles données à votre liste principale et faites notifyItemInserted () au lieu de notifyDataSetChanged, de cette manière, vous verrez également l’animation par défaut ajouter de recyclerView.
lorsque vous remplissez tous votre liste appelez la méthode ci-dessous.
if (adapter != null) // it works second time and later
adapter.notifyDataSetChanged();
else { // it works first time
adapter = new AdapterClass(context,list);
listView.setAdapter(adapter);
}