通过API在RecyclerView中传递数据

huangapple go评论75阅读模式
英文:

Passing data in recycler view from API

问题

public class CountriesDetails extends AppCompatActivity {

    TextView tvCountry, tvCases, tvRecovered, tvDeaths;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_countries_details2);

        tvCountry = findViewById(R.id.tvCountry);
        tvCases = findViewById(R.id.tvCases);
        tvRecovered = findViewById(R.id.tvRecovered);
        tvDeaths = findViewById(R.id.tvTotalDeaths);

        String positionCountry = getIntent().getStringExtra("Country");
        Log.i("country name", positionCountry);

        // You can fetch the corresponding country's data from the countryList
        // and then set the data to the TextViews.

        for (Countries_data country : AffectedCountries.countryList) {
            if (country.getCountry().equals(positionCountry)) {
                tvCountry.setText(country.getCountry());
                tvCases.setText(country.getCases());
                tvRecovered.setText(country.getRecovered());
                tvDeaths.setText(country.getDeaths());
                break;  // Exit the loop after finding the matching country
            }
        }
    }
}

Regarding your question about showing the data, you don't need a separate RecyclerView for the details in this case. You can use the existing CountriesDetails activity to display the detailed information of a selected country. The data for the selected country is passed through the intent extra, as shown in the code above.

You can use the same activity to display the data in a different layout or design if you prefer. Just make sure to adjust the layout elements and their IDs accordingly. The CountriesDetails activity should work well for displaying the detailed data of a selected country.

英文:

I tried to make a covid-19 tracking app by watching Youtube tutorials.

My app shows the country list with flags and when you click on any country it opens an activity and shows the details of that country i.e total cases, deaths, recovered, etc. The video on Youtube uses ListView and I am using recyclerView

I fetched the country list successfully and set onClickListener on the view and it opens second activity which shows the case in detail. But I don't know how to show the data.

my adapter class:

class Countries_adapter extends RecyclerView.Adapter<Countries_adapter.MyViewHolder> {


    Context ct;
    List<Countries_data> list;

    public Countries_adapter(Context context,List<Countries_data> country)
    {
        ct=context;
        list=country;
    }


    @Override
    public MyViewHolder onCreateViewHolder( ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(ct).inflate(R.layout.countries_row,parent,false);
        return new MyViewHolder(v);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, final int position) {

        holder.tvCountryName.setText(list.get(position).getCountry());
        holder.tvtotal.setText(list.get(position).getActive());
        Glide.with(ct).load(list.get(position).getFlag()).into(holder.imageView);

        holder.linearLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent i = new Intent(ct,CountriesDetails.class);
                i.putExtra("Country",list.get(position).getCountry());
                ct.startActivity(i);
            }
        });


    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        TextView tvCountryName,tvtotal;
        ImageView imageView;
        LinearLayout linearLayout;
        public MyViewHolder( View itemView) {
            super(itemView);

            tvCountryName = itemView.findViewById(R.id.tvCountryName);
            tvtotal=itemView.findViewById(R.id.tvCountrytotalcaese);
            imageView = itemView.findViewById(R.id.imageFlag);
            linearLayout=itemView.findViewById(R.id.linear_layout);

        }
    }

my AffectedCoutries class activity is as follows:

    public class AffectedCountries extends AppCompatActivity {
    
        EditText edtSearch;
       RecyclerView recyclerView;
        SimpleArcLoader simpleArcLoader;
        public static ArrayList countryList = new ArrayList<>();
        Countries_data countryData;
        Countries_adapter  CountriesAdapter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_affected_countries);
    
            edtSearch = findViewById(R.id.edtSearch);
            recyclerView=findViewById(R.id.recyclerAffectedCountries);
            simpleArcLoader = findViewById(R.id.loader);
    
          fetchData();
        }
        private void fetchData() {
    
            String url  = "https://corona.lmao.ninja/v2/countries/";
    
            simpleArcLoader.start();
    
            StringRequest request = new StringRequest(Request.Method.GET, url,
                    new Response.Listener<String>() {
                        @Override
                        public void onResponse(String response) {
    
                            try {
    
                                JSONArray jsonArray = new JSONArray(response);
    
                                for(int i=0;i<jsonArray.length();i++){
    
                                    JSONObject jsonObject = jsonArray.getJSONObject(i);
    
                                    String countryName = jsonObject.getString("country");
                                    String cases = jsonObject.getString("cases");
                                    String todayCases = jsonObject.getString("todayCases");
                                    String deaths = jsonObject.getString("deaths");
                                    String todayDeaths = jsonObject.getString("todayDeaths");
                                    String recovered = jsonObject.getString("recovered");
                                    String active = jsonObject.getString("active");
                                    String critical = jsonObject.getString("critical");
    
                                    JSONObject object = jsonObject.getJSONObject("countryInfo");
                                    String flagUrl = object.getString("flag");
    
                                    countryData = new Countries_data(flagUrl,countryName,cases,todayCases,deaths,todayDeaths,recovered,active,critical);
                                    countryList.add(countryData);
                                }
    
                               CountriesAdapter = new Countries_adapter(AffectedCountries.this,countryList);
                                recyclerView.setLayoutManager(new LinearLayoutManager(AffectedCountries.this));
                                recyclerView.setAdapter(CountriesAdapter);
                                simpleArcLoader.stop();
                                simpleArcLoader.setVisibility(View.GONE);
    
    
                            } catch (JSONException e) {
                                e.printStackTrace();
                                simpleArcLoader.start();
                                simpleArcLoader.setVisibility(View.GONE);
                                Toast.makeText(AffectedCountries.this,"catch response", Toast.LENGTH_SHORT).show();
                            }
    
    
                        }
                    }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    simpleArcLoader.stop();
                    simpleArcLoader.setVisibility(View.GONE);
                    Toast.makeText(AffectedCountries.this,"error response", Toast.LENGTH_SHORT).show();
                }
            });
    
            RequestQueue requestQueue = Volley.newRequestQueue(this);
            requestQueue.add(request);

    }
}

my Countries_data class(model class)

public class Countries_data {
    public String country;
    public String cases;
    public String todayCases;
    public String deaths;
    public String todayDeaths;
    public String recovered;
    public String active;
    public String critical;
    public String flag;
    
    public Countries_data(String flag, String country, String cases, String 
           todayCases, String deaths, String todayDeaths, String recovered, 
          String active, String critical) {
       

        this.country = country;
        this.cases = cases;
        this.todayCases = todayCases;
        this.deaths = deaths;
        this.todayDeaths = todayDeaths;
        this.recovered = recovered;
        this.active = active;
        this.critical = critical;
        this.flag = flag;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getCases() {
        return cases;
    }

    public void setCases(String cases) {
        this.cases = cases;
    }

    public String getTodayCases() {
        return todayCases;
    }

    public void setTodayCases(String todayCases) {
        this.todayCases = todayCases;
    }

    public String getDeaths() {
        return deaths;
    }

    public void setDeaths(String deaths) {
        this.deaths = deaths;
    }

    public String getTodayDeaths() {
        return todayDeaths;
    }

    public void setTodayDeaths(String todayDeaths) {
        this.todayDeaths = todayDeaths;
    }

    public String getRecovered() {
        return recovered;
    }

    public void setRecovered(String recovered) {
        this.recovered = recovered;
    }

    public String getActive() {
        return active;
    }

    public void setActive(String active) {
        this.active = active;
    }

    public String getCritical() {
        return critical;
    }

    public void setCritical(String critical) {
        this.critical = critical;
    }

    public String getFlag() {
        return flag;
    }

    public void setFlag(String flag) {
        this.flag = flag;
    }
}

my Country_details class

public class CountriesDetails extends AppCompatActivity {

    TextView tvCountry, tvCases, tvRecovered,tvdeaths;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_countries_details2);

        tvCountry = findViewById(R.id.tvCountry);
        tvCases = findViewById(R.id.tvCases);
        tvRecovered = findViewById(R.id.tvRecovered);
        tvdeaths=findViewById(R.id.tvTotalDeaths);

        String positionCountry = getIntent().getStringExtra("Country");
        Log.i("country name", positionCountry);

    }
}

How to set the data in tvcases?

How can I show the data? Do I have to create a separate recycler view and then fetch the data from the API or can I use my main activity to show the data?

答案1

得分: 0

I have some sad information for you: Google Play policy restricts such apps from being published in the store... especially when you are showing deaths count. Been there, done that, my app was blocked...

Besides the above:

You are passing the country name in the intent:

i.putExtra("Country", list.get(position).getCountry());

But when trying to read "position" in the details Activity, it will always be 0 (default).

Edit due to comments:

Pass the position of the clicked View:

holder.linearLayout.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent i = new Intent(ct, CountriesDetails.class);
        i.putExtra("position", position);
        ct.startActivity(i);
    }
});

In the CountriesDetails onCreate method, receive this position and restore the proper Countries_data object from your static countryList array in AffectedCountries:

int position = getIntent().getIntExtra("position", 0);
Countries_data country = AffectedCountries.countryList.get(position);
tvCountry.setText(country.getCountry());

That should work, but this isn't the best way to store data. In fact, it's very weak. After downloading data (list of countries), you should store it somehow, e.g., using SQLite/Room lib or at least SharedPreferences. Then, in the details activity, you should restore int position and use it to retrieve the proper object from the database or preferences, instead of directly from the static array.

It may also be useful to implement the Parcelable interface for your Countries_data. This will allow you to put the whole Countries_data object into Intent extras, not just the primitive int with the position in the array. In this case, the details activity won't even need access to the whole array or SQL database/preferences; it will get the whole object straight from the Intent extras.

英文:

I have some sad information for you: Google Play policy restricts such apps from being published in store... especially when you are showing deaths count. Been there, done that, my app was blocked...

besides above:

you are passing country name in intent:

i.putExtra("Country",list.get(position).getCountry());

but trying to read "position" in details Activity - it will be always 0 (default)

edit due to comments:

pass position of clicked View

holder.linearLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent i = new Intent(ct,CountriesDetails.class);
            i.putExtra("position", position);
            ct.startActivity(i);
        }
    });

in CountriesDetailss onCreate method receive this position and restore proper Countries_data object from your static countryList array in AffectedCountries

int position = getIntent().getIntExtra("position", 0);
Countries_data country = AffectedCountries.countryList.get(position);
tvCountry.setText(country.getCountry());

that should work, but this isn't best way to store data, in fact its very weak... after downloading data (list of countries) you should store it somehow, e.g. SQLite/Room lib or at least SharedPreferences... then in details activity you should restore int position and using it take proper object from database or preferences, instead of stright from static array

it may be also useful to implement Parcelable inteface to your Countries_data - this will allow to put whole Countries_data object into Intents extras, not only primitive int with position in array. in this case details activity won't even need access to whole array or sql database/preferences, it will get whole object straight from Intents extras

huangapple
  • 本文由 发表于 2020年9月15日 20:26:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/63901821.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定