Я работаю над приложением android
для отображения Coronavirus
JSON
данных с использованием RecyclerView
. Первоначально мне удалось отобразить данные JSON в моем RecyclerView
, но в нем отображался список всех стран, в точности как я проанализировал данные JSON. Теперь я хочу добавить поисковый фильтр, чтобы пользователь мог искать определенную c страну. Я пытался добиться этого путем реализации Filterable
в моем классе RecyclerView Adapter. Вот шаги, которые я предпринял. Я начал с создания пользовательского класса объектов Country с методами getter
и setter
. Затем я сохранил результат, полученный от сетевого запроса после анализа данных JSON
в Arraylist
странах. Пожалуйста, смотрите код ниже
public final class CovidJSON_Utils {
public static String[] getSimpleStringFromJson(Context context, String codivJsonString)
throws JSONException {
final String COV_COUNTRY = "Countries";
final String COV_CONFIRMED = "confirmed";
final String COV_DEATHS = "deaths";
final String COV_MESSAGE_CODE = "code";
String[] parsedCovidData = null;
ArrayList<Country> countries = new ArrayList<>();
JSONObject covidJsonObject = new JSONObject(codivJsonString);
if (covidJsonObject.has(COV_MESSAGE_CODE)) {
int errorCode = covidJsonObject.getInt(COV_MESSAGE_CODE);
switch (errorCode) {
case HttpURLConnection.HTTP_OK:
break;
case HttpURLConnection.HTTP_NOT_FOUND:
return null;
default:
return null;
}
}
JSONArray countryCovidArray = covidJsonObject.getJSONArray(COV_COUNTRY);
parsedCovidData = new String[countryCovidArray.length()];
for (int i = 0; i < countryCovidArray.length(); i++) {
Country tempCountry = new Country();
JSONObject countryJSONObject = countryCovidArray.getJSONObject(i);
String Country = countryJSONObject.getString("Country");
String Confirmed = String.valueOf(countryJSONObject.getInt("TotalConfirmed"));
String Deaths = String.valueOf(countryJSONObject.getInt("TotalDeaths"));
parsedCovidData[i] = Country + "- Cases " + Confirmed + "- Deaths " + Deaths;
tempCountry.setCountryName(Country);
tempCountry.setTotalConfirmed(Confirmed);
tempCountry.setTotalDeaths(Deaths);
countries.add(tempCountry);
countries.clear();
}
return parsedCovidData;
}
}
После этого в RecyclerView Adapter class
я добавил getFilter()
метод для получения фильтрованного ArrayList
. Я изменил конструктор Corona_Stats_Adapter
, чтобы передать List<Country>
. Но из моего основного действия, когда я вызываю конструктор Corona_Stats_Adapter
, как передать правильные ArrayList
, которые я создал, анализируя данные JSON
в классе CovidJSON_Utils
.
public class Corona_Stats_Adapter extends RecyclerView.Adapter<Corona_Stats_Adapter.Corona_Stats_AdapterViewHolder>
implements Filterable {
private Context context;
private List<Country> countryList;
private List<Country> countryListFiltered;
private String[] mCoronaData;
public Corona_Stats_Adapter(Context context, List<Country> countryList){
this.context = context;
this.countryList = countryList;
this.countryListFiltered = countryList;
}
@NonNull
@Override
public Corona_Stats_AdapterViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
Context context = viewGroup.getContext();
int LayoutIdForListItem =R.layout.corona_stats_list_item;
LayoutInflater inflater =LayoutInflater.from(context);
boolean ShouldAttachToParentImmediately = false;
View view = inflater.inflate(LayoutIdForListItem,viewGroup,ShouldAttachToParentImmediately);
return new Corona_Stats_AdapterViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull Corona_Stats_AdapterViewHolder corona_stats_adapterViewHolder, int position) {
final Country country = countryListFiltered.get(position);
corona_stats_adapterViewHolder.mCoronaTextView.setText(country.getCountryName());
String coronaStats = mCoronaData[position];
corona_stats_adapterViewHolder.mCoronaTextView.setText(coronaStats);
}
@Override
public int getItemCount() {
if(null == mCoronaData) return 0;
//return mCoronaData.length;
return countryListFiltered.size();
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if(charString.isEmpty()){
countryListFiltered = countryList;
} else {
List<Country> filteredList = new ArrayList<>();
for(Country row : countryList){
if(row.getCountryName().toLowerCase().contains(charString.toLowerCase()) ){
filteredList.add(row);
}
}
countryListFiltered = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = countryListFiltered;
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
countryListFiltered = (ArrayList<Country>) filterResults.values;
notifyDataSetChanged();
}
};
}
public class Corona_Stats_AdapterViewHolder extends RecyclerView.ViewHolder {
public final TextView mCoronaTextView;
public Corona_Stats_AdapterViewHolder(@NonNull View view) {
super(view);
mCoronaTextView = (TextView) view.findViewById(R.id.tv_corona_data);
}
}
public void setCoronaData(String[] coronaData){
mCoronaData = coronaData;
notifyDataSetChanged();
}
}
Код класса страны
public class Country {
String CountryName;
String TotalConfirmed;
String TotalDeaths;
public Country(){
}
public String getCountryName(){return CountryName;}
public String getTotalConfirmed(){return TotalConfirmed;}
public String getTotalDeaths(){return TotalDeaths;}
public void setCountryName(String countryName) {
CountryName = countryName;
}
public void setTotalConfirmed(String totalConfirmed) {
TotalConfirmed = totalConfirmed;
}
public void setTotalDeaths(String totalDeaths) {
TotalDeaths = totalDeaths;
}
}
Основной код деятельности ..
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private Corona_Stats_Adapter mCorona_Stats_Adapter;
private TextView mErrorDisplay;
private ProgressBar mProgressBar;
//ArrayList<Country> countries = new ArrayList<Country>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.corona_stats);
mRecyclerView = (RecyclerView)findViewById(R.id.Corona_stats_recycler);
mErrorDisplay = (TextView) findViewById(R.id.tv_error_message_display);
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setHasFixedSize(true);
mCorona_Stats_Adapter = new Corona_Stats_Adapter();
mRecyclerView.setAdapter(mCorona_Stats_Adapter);
mProgressBar = (ProgressBar)findViewById(R.id.pb_loading_indicator) ;
loadCoronaData();
}
private void loadCoronaData(){
showCoronaDataView();
//String Country = String.valueOf(mSearchQuery.getText());
new Fetch_data().execute();
}
private void showCoronaDataView(){
mErrorDisplay.setVisibility(View.INVISIBLE);
mRecyclerView.setVisibility(View.VISIBLE);
}
private void showErrorMessage(){
mRecyclerView.setVisibility(View.INVISIBLE);
mErrorDisplay.setVisibility(View.VISIBLE);
}
public class Fetch_data extends AsyncTask<Void,Void,String[]> {
@Override
protected void onPreExecute() {
super.onPreExecute();
mProgressBar.setVisibility(View.VISIBLE);
}
@Override
protected String[] doInBackground(Void... voids) {
URL covidRequestURL = NetworkUtils.buildUrl();
try {
String JSONCovidResponse = NetworkUtils.getResponseFromHttpUrl(covidRequestURL);
String[] simpleJsonCovidData = CovidJSON_Utils.getSimpleStringFromJson(MainActivity.this, JSONCovidResponse);
return simpleJsonCovidData;
} catch (IOException | JSONException e) {
e.printStackTrace();
return null;
}
}
@Override
protected void onPostExecute(String[] coronaData) {
mProgressBar.setVisibility(View.INVISIBLE);
if(coronaData !=null){
showCoronaDataView();
mCorona_Stats_Adapter.setCoronaData(coronaData);
} else{
showErrorMessage();
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int menuItemThatWasSelected = item.getItemId();
if(menuItemThatWasSelected == R.id.action_search){
Toast.makeText(MainActivity.this, "Search clicked", Toast.LENGTH_LONG).show();
}
return super.onOptionsItemSelected(item);
}
}