如何在RecyclerView中添加搜索过滤器以过滤已解析的JSON数据?

问题描述 投票:0回答:1

我正在使用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数据,然后...

java android json android-recyclerview searchview
1个回答
0
投票

请在MainActivity中取消注释并检查以下行

© www.soinside.com 2019 - 2024. All rights reserved.