我正在使用RecyclerView
来显示国家/地区列表,确诊病例总数和冠状病毒死亡总数的Android应用程序。我从网站获取JSON
数据,然后解析该数据。 JSON数据为我提供了所有国家/地区的列表,以及每个国家/地区的总数。因此,RecyclerView
显示了所有国家的清单以及各自的病例数。我想在RecyclerView中添加搜索选项,以便用户可以搜索特定的国家。我用来获取JSON数据的url不支持传递查询参数来获取特定国家/地区的案件总数,因此我决定通过在getFilter()
类中实现Filterable
来使用RecycleyView Adapter
方法。我创建了一个自定义Country Object class
,然后创建了一个ArrayList<Country>
来存储JSON数据。我使用AsyncTask
进行网络请求。我还创建了一个搜索菜单。当我运行该应用程序时,该应用程序可以成功运行而不会崩溃,但不会显示任何结果。如果我单击“搜索”并键入国家名称,它仍然不会显示任何内容。有人可以帮我找出代码中的错误吗。为什么我出现黑屏?这是我正在使用的代码。
menu main.xml
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:title="@string/search" android:orderInCategory="1" app:showAsAction ="ifRoom" android:id="@+id/action_search" app:actionViewClass="androidx.appcompat.widget.SearchView" /> </menu>
[RecyclerView的查看项目corona_stats_list_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/tv_corona_data" style="@style/TextAppearance.AppCompat.Large" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="16dp"/> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="#dadada" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" /> </LinearLayout>
国家对象类别
package com.passengerearth.coronago; 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; } }
解析JSON数据并将其存储在ArrayList <>
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; } }
[RecyclerView适配器类Corona_stats_Adapter.java
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(); } }
最后是MainActivity.Java
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private Corona_Stats_Adapter mCorona_Stats_Adapter;
private TextView mErrorDisplay;
private ProgressBar mProgressBar;
private SearchView searchView;
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 ArrayList<Country> doInBackground(Void... voids) {
URL covidRequestURL = NetworkUtils.buildUrl();
try {
String JSONCovidResponse = NetworkUtils.getResponseFromHttpUrl(covidRequestURL);
ArrayList<Country> coronaData = CovidJSON_Utils.getSimpleStringFromJson(MainActivity.this, JSONCovidResponse);
return coronaData;
} 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.notifyDataSetChanged();
// mCorona_Stats_Adapter.setCoronaData(coronaData);
} else{
showErrorMessage();
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView = (SearchView) menu.findItem(R.id.action_search)
.getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setMaxWidth(Integer.MAX_VALUE);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
mCorona_Stats_Adapter.getFilter().filter(query);
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
mCorona_Stats_Adapter.getFilter().filter(newText);
return false;
}
});
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int menuItemThatWasSelected = item.getItemId();
if(menuItemThatWasSelected == R.id.action_search){
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onBackPressed() {
if (!searchView.isIconified()) {
searchView.setIconified(true);
return;
}
super.onBackPressed();
}
}
我正在使用RecyclerView来显示国家列表,确诊病例总数和冠状病毒死亡总数的Android应用程序。我正在从网站获取JSON数据,然后...
请在MainActivity中取消注释并检查以下行