[英]How to pass an ArrayList filled with JSON data to a constructor for RecyclerView Adapter?
我正在開發一個android
應用程序,以使用RecyclerView
顯示Coronavirus
JSON
數據。 最初,我成功地在我的RecyclerView
中顯示了 JSON 數據,但它顯示了我如何解析 JSON 數據的所有國家/地區的列表。 現在我想添加一個搜索過濾器,以便用戶可以搜索特定的國家。 我試圖通過在我的 RecyclerView 適配器 class 中實現Filterable
來實現這一點。 這是我采取的步驟。 我首先使用getter
和setter
方法創建自定義 Country object class。 然后,我在一個名為國家的Arraylist
中解析了JSON
數據后,將我從網絡請求中得到的結果存儲起來。 請看下面的代碼
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();
}
}
國家 class 代碼
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);
}
}
好的,所以您應該將此處的返回類型從String[]
更改為List <Country>
所以這:
public final class CovidJSON_Utils {
public static String[] getSimpleStringFromJson(Context context, String codivJsonString)
變成這樣:
public final class CovidJSON_Utils {
public static List <Country> getSimpleStringFromJson(Context context, String codivJsonString)
現在你必須返回列表所以這樣做
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);
}
return countries;
現在在您的主要活動中, asyncTask 更改返回類型
這個:
public class Fetch_data extends AsyncTask<Void,Void,String[]>
對此:
public class Fetch_data extends AsyncTask<Void,Void,List <Country>>
在后台做變成:
@Override
protected List <Country> doInBackground(Void... voids) {
URL covidRequestURL = NetworkUtils.buildUrl();
try {
String JSONCovidResponse = NetworkUtils.getResponseFromHttpUrl(covidRequestURL);
List <Country> simpleJsonCovidData = CovidJSON_Utils.getSimpleStringFromJson(MainActivity.this, JSONCovidResponse);
return simpleJsonCovidData;
} catch (IOException | JSONException e) {
e.printStackTrace();
return null;
}
}
最后:
.........
showCoronaDataView();
List <Country> countriesData = new Fetch_data().execute();
mCorona_Stats_Adapter = new Corona_Stats_Adapter(this,countriesData);
mRecyclerView.setAdapter(mCorona_Stats_Adapter);
...........
首先,您必須從CovidJSON_Utils
返回ArrayList<Country>
public final class CovidJSON_Utils {
public static ArrayList<Country> 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 countries;
}
}
當您從CovidJSON_Utils
class 獲取它時,它將返回ArrayList<Country>
。 之后將其分配給適配器。
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(this, countries);
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,ArrayList<Country>> {
@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);
ArrayList<Country> corornaData = CovidJSON_Utils.getSimpleStringFromJson(MainActivity.this, JSONCovidResponse);
return corornaData;
} catch (IOException | JSONException e) {
e.printStackTrace();
return null;
}
}
@Override
protected void onPostExecute(ArrayList<Country> coronaData) {
mProgressBar.setVisibility(View.INVISIBLE);
if(coronaData !=null){
showCoronaDataView();
countries.addAll(coronaData);
mCorona_Stats_Adapter.notifyDatasetChnaged();
} 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);
}
}
希望您能得到您的答復,如果您有任何疑問可以發表評論,我會為您提供幫助。
快樂編碼::)
在您的構造函數中,像這樣創建原始列表的副本,
private List<Country> countryList;
private List<Country> countryListFull;
public Corona_Stats_Adapter(Context context, List<Country> countryList){
this.context = context;
this.countryList = countryList;
countryListFull = new ArrayList<>(countryList);
}
現在,在您的執行過濾方法中:
protected FilterResults performFiltering(CharSequence charSequence) {
List<Country> filteredCountryList= new ArrayList<>();
if (charSequence== null || charSequence.length() == 0) {
filteredCountryList.addAll(countryListFull);
} else {
String filterPattern = charSequence.toString().toLowerCase().trim();
for (Country country: CountryListFull
) {
if (country.getCountryName().toLowerCase().contains(filterPattern.toLowerCase())
) {
filteredCountryList.add(country);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredCountryList;
return results;
}
發布結果方法:
protected void publishResults(CharSequence charSequence, FilterResults results) {
countryList.clear();
countryList.addAll((List) results.values);
notifyDataSetChanged();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.