I don't know why I am getting this error.
I had implemented filterResults()
.
Actually, when I search first time in edit text and click on it, it works fine.
Then when I come back and search for some city again, it shows 2 same entries. I have added screenshots.
Then when I come back and search 3rd time I got 3 same entries for each city searched.
My java class:
package com.wordpress.myselfnikunj.cofighter;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.navigation.Navigation;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.Volley;
import com.wordpress.myselfnikunj.cofighter.Adapters.CountryListAdapter;
import com.wordpress.myselfnikunj.cofighter.Model.CountryNamesModel;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class AffectedCountriesFragment extends Fragment {
EditText searchEditText;
ListView listView;
public static List<CountryNamesModel> countryNamesModelList = new ArrayList<>();
CountryNamesModel countryNamesModel;
CountryListAdapter countryListAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_affected_countries, container, false);
searchEditText = (EditText) view.findViewById(R.id.searchEditText);
listView = (ListView) view.findViewById(R.id.countriesListView);
countryListAdapter = new CountryListAdapter(getContext(), countryNamesModelList);
// listView.setAdapter(countryListAdapter);
fetchData();
searchEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
countryListAdapter.getFilter().filter(charSequence);
countryListAdapter.notifyDataSetChanged();
}
@Override
public void afterTextChanged(Editable editable) {
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Bundle position = new Bundle();
position.putInt("position", i);
Navigation.findNavController(view).navigate(R.id.action_affectedCountriesFragment_to_countryDetailsFragment, position);
}
});
return view;
}
private void fetchData() {
String Url = "https://corona.lmao.ninja/v2/countries/";
RequestQueue requestQueue = Volley.newRequestQueue(getContext());
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(
Url,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.i("hehes","entered");
try {
Log.i("hehe", response.toString());
for (int i = 0; i < response.length(); i++) {
JSONObject jsonObject = response.getJSONObject(i);
String countryName = jsonObject.getString("country");
String cases = jsonObject.getString("cases");
String todayCases = jsonObject.getString("todayCases");
String deaths = jsonObject.getString("deaths");
String recovered = jsonObject.getString("recovered");
String todayDeaths = jsonObject.getString("todayDeaths");
String active = jsonObject.getString("active");
String critical = jsonObject.getString("critical");
JSONObject object = jsonObject.getJSONObject("countryInfo");
String flagUrl = object.getString("flag");
countryNamesModel = new CountryNamesModel(getContext(),flagUrl, countryName, cases, todayCases, deaths, todayDeaths, recovered, active, critical);
countryNamesModelList.add(countryNamesModel);
}
countryListAdapter.notifyDataSetChanged();
listView.setAdapter(countryListAdapter);
}catch (Exception e) {
Log.i("error", e.getMessage());
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.i("errors", error.getMessage());
Toast.makeText(getContext(), error.getMessage(), Toast.LENGTH_SHORT).show();
}
}
);
requestQueue.add(jsonArrayRequest);
}
My custom Adapter
package com.wordpress.myselfnikunj.cofighter.Adapters;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.bumptech.glide.Glide;
import com.wordpress.myselfnikunj.cofighter.AffectedCountriesFragment;
import com.wordpress.myselfnikunj.cofighter.Model.CountryNamesModel;
import com.wordpress.myselfnikunj.cofighter.R;
import com.wordpress.myselfnikunj.cofighter.UpdatesFragment;
import java.util.ArrayList;
import java.util.List;
public class CountryListAdapter extends ArrayAdapter<CountryNamesModel> {
private Context context;
private List<CountryNamesModel> countryModelList;
private List<CountryNamesModel> countryModelListFiltered;
public CountryListAdapter( Context context, List<CountryNamesModel> countryModelList) {
super(context, R.layout.countryitem, countryModelList);
this.context = context;
this.countryModelList = countryModelList;
this.countryModelListFiltered = countryModelList;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.countryitem, null, true);
TextView tvCountryName = view.findViewById(R.id.countryName);
ImageView imageView = view.findViewById(R.id.countryImageFlag);
tvCountryName.setText(countryModelListFiltered.get(position).getCountry());
Glide.with(context).load(countryModelListFiltered.get(position).getFlag()).into(imageView);
return view;
}
@Override
public int getCount() {
return countryModelListFiltered.size();
}
@Nullable
@Override
public CountryNamesModel getItem(int position) {
return countryModelListFiltered.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@NonNull
@Override
public Filter getFilter() {
Filter filter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
FilterResults filterResults = new FilterResults();
if (charSequence == null
|| charSequence.length() == 0
) {
filterResults.count = countryModelList.size();
filterResults.values = countryModelList;
} else {
List<CountryNamesModel> resultsModel = new ArrayList<>();
String searchStr = charSequence.toString().toLowerCase();
for (CountryNamesModel itemsModel: countryModelList) {
if(itemsModel.getCountry().toLowerCase().contains(searchStr)) {
resultsModel.add(itemsModel);
}
filterResults.count = resultsModel.size();
filterResults.values = resultsModel;
}
}
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults results) {
countryModelListFiltered = (List<CountryNamesModel>) results.values;
UpdatesFragment.countryNamesModelList = (List<CountryNamesModel>) results.values;
//AffectedCountriesFragment.countryNamesModelList = (List<CountryNamesModel>) results.values;
notifyDataSetChanged();
}
};
return filter;
}
}
Screenshots
When you navigate to another fragment view of the
AffectedCountriesFragment
getting destroyed andpublic void onDestroyView()
is called. When you return backpublic View onCreateView
is called again. But your fragment was not totally destroyed and all of its variables still exist and are in the state they were left.It means that when you navigate to the next fragment your
countryNamesModelList
stays filled and when you return back to theAffectedCountriesFragment
the same filled list getting filled again resulting in duplicated entries.What you can do?
Track the state of your fragment. Create a new class-level variable
private View view;
that will hold the view of your fragment.Make sure you are not missing something in an understanding of Activity and Fragment lifecycles. Here is a good example of their lifecycles.