【问题标题】:How to add a search filter in RecyclerView to filter through parsed JSON data? edited如何在 RecyclerView 中添加搜索过滤器来过滤解析的 JSON 数据?已编辑
【发布时间】:2020-04-17 10:51:29
【问题描述】:

我正在开发一个 Android 应用程序,该应用程序显示受冠状病毒影响的国家/地区列表、确诊病例总数和总死亡人数。我正在使用 JSON API 来获取数据并使用 RecyclerView 显示它。该应用程序运行良好,我得到了所有国家的列表及其各自的病例数。我想添加一个搜索选项,以便用户可以过滤列表并找到特定的国家。我怎么做?我是编程新手,如果有人可以提供帮助,那就太棒了。 这是代码sn -p

MainActivity.java

    private RecyclerView mRecyclerView;
    private Corona_Stats_Adapter mCorona_Stats_Adapter;
    private TextView mErrorDisplay;
    private ProgressBar mProgressBar;

    @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();
            }

        }
    }
}

RecyclerView 适配器类 Corona_stats_Adapter.java

public class Corona_Stats_Adapter extends RecyclerView.Adapter<Corona_Stats_Adapter.Corona_Stats_AdapterViewHolder>
  {

    private Context context;
   // private List<Country> countryList;
   // private List<Country> countryListFiltered;
    private String[] mCoronaData;
    public Corona_Stats_Adapter(){
    }

    @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) {

        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();
    }

    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();
        }

}

解析 CovidJSON_Utils.java 中的 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;
        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++) {

                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;

            }
            return parsedCovidData;


        }


    }

【问题讨论】:

    标签: java android json android-recyclerview searchview


    【解决方案1】:

    问题在于 MainActivity.Oncreate 方法中的以下初始化

    mCorona_Stats_Adapter = new Corona_Stats_Adapter(this,countries);
    

    在 onPostExecute 方法中使用更新的国家数据初始化适配器。

    希望这会对你有所帮助。

    【讨论】:

    • 当我取消注释该行时,它会在“(coronaData)”下给出一个红色下划线,并说 setCoronaData(string[]) 不能应用于 Corona_stats_Adapter。我在 Corona_stats_Adapter 类中创建了 setCoronaData() 函数。谢谢
    • 非常感谢您的回复。当我添加 mCorona_Stats_Adapter = new Corona_Stats_Adapter(this,countries);到 onPostExecute 它说 Corona_Stats_Adapter (context, List cannot be applied to (ArrayList .. 我在我的 Corona_stats_Adapter 类中使用了 List
    • 只需将其更改为 list.. ArrayList countries -> List mainactivity中的县
    • 我这样做了。它解决了错误。我运行了应用程序,它仍然显示一个空白屏幕。我还取消了“mCorona_Stats_Adapter.setCoronaData(coronaData);”行的注释。正如您在之前的回答中提到的。谢谢
    • 您是否检查了 coronadata 对象的大小。您是从服务器获取数据吗?
    【解决方案2】:

    从服务器获取数据后,您必须设置arraylist以更新适配器中的国家/地区数据。

    Public void setCoronaData (Arraylist coronaData) {
      countryList = coronaData;
      notifyDataSetChanged ();
    }
    

    【讨论】:

    • 这让我取消注释行 mCorona_Stats_Adapter.setCoronaData(coronaData);在 onPostExecute();但是当我运行该应用程序时仍然出现空白屏幕。
    猜你喜欢
    • 1970-01-01
    • 2019-06-12
    • 2018-07-07
    • 2018-05-15
    • 2018-07-04
    • 2017-11-11
    • 2018-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多