簡體   English   中英

如何將充滿 JSON 數據的 ArrayList 傳遞給 RecyclerView Adapter 的構造函數?

[英]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來實現這一點。 這是我采取的步驟。 我首先使用gettersetter方法創建自定義 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM