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?
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
Related
I have a small problem that I can't solve:
I have an array of objects (Country) that I get them from API.
One of the parameters in each object(Country) is an array of border Country - value name = border.
In one Fragment I show all the countries that get from API.
One of my goals is to click on a some country and will opens a new screen where all the countries bordering the country I clicked on will be shown.
I already have all the logic of switching between screens, RecyclerViews on both screen and more, but I don't know how to create and parse the new array of the bordering countries to the new screen.
That what i have for now:
All countries adapter:
public class CountryAdapter extends RecyclerView.Adapter<CountryAdapter.CountryViewHolder> {
#Override
public void onBindViewHolder(#NonNull CountryViewHolder holder, final int position) {
holder.mTVCountryName.setText(countries.get(position).getName());
holder.mTVCountryNativeName.setText(countries.get(position).getNativeName());
GlideToVectorYou
.init()
.with(mContext)
.load(Uri.parse(countries.get(position).getFlag()), holder.mCountryFlag);
holder.mCountryFlag.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (iOnItemClickListener != null) {
//Array list of all border countries by alpha3 value
List<String> borderCountriesAlpha3 = new ArrayList<>();
for (int i = 0; i < countries.get(position).getBorders().size(); i++) {
try {
borderCountriesAlpha3.add(countries.get(position).getBorders().get(i));
} catch (Exception e) {
}
}
iOnItemClickListener.onItemClick(position, borderCountriesAlpha3);
}
}
});
}
Getting the data from API:
public void getAllCountries(){
ApiService apiService = ApiClient.getRetrofitInstance().create(ApiService.class);
call = apiService.getAllCountries();
call.enqueue(new Callback<List<Country>>() {
#Override
public void onResponse(Call<List<Country>> call, Response<List<Country>> response) {
mCountryPresenter.generateDataList(response.body());
}
#Override
public void onFailure(Call<List<Country>> call, Throwable t) {
}
});
}
Country pojo class:
public class Country implements Comparable<Country> {
#SerializedName("name")
#Expose
private String name;
#SerializedName("alpha3Code")
#Expose
private String alpha3Code;
#SerializedName("borders")
#Expose
private List<String> borders = null;
#SerializedName("nativeName")
#Expose
private String nativeName;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAlpha3Code() {
return alpha3Code;
}
public void setAlpha3Code(String alpha3Code) {
this.alpha3Code = alpha3Code;
}
public List<String> getBorders() {
return borders;
}
public void setBorders(List<String> borders) {
this.borders = borders;
}
public String getNativeName() {
return nativeName;
}
public void setNativeName(String nativeName) {
this.nativeName = nativeName;
}
}
Fragment that contain recycler view for all countries:
public class CountryListFragment extends Fragment implements CountryPresenter {
private View view;
private RecyclerView mRVCountries;
private CountryAdapter mCountryAdapter;
private CountriesView mCountriesView;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_country_list, container, false);
initView(view);
initClasses();
initContentView();
return view;
}
private void initClasses() {
mCountriesView = new CountriesView(this, getContext());
}
private void initView(View view) {
mRVCountries = view.findViewById(R.id.rvCountries);
}
private void initContentView() {
mCountriesView.getAllCountries();
}
#Override
public void generateDataList(List<Country> countries) {
mCountryAdapter = new CountryAdapter(countries, getContext(), getActivity());
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
mRVCountries.setLayoutManager(layoutManager);
mRVCountries.setAdapter(mCountryAdapter);
mCountryAdapter.setiOnItemClickListener(new CountryAdapter.OnItemClickListener() {
#Override
public void onItemClick(int position, List<String> borderCountries) {
Log.d("myDebug", "onItemClick: " + position + " " + borderCountries);
}
});
}
public void sortByNativeName() {
mCountryAdapter.sortByNativeName();
}
public void sortByArea() {
mCountryAdapter.sortByArea();
}
}
You can use Java's streaming API or Collections API to search a list, copy a sublist to another etc. Here is an example of your requirement of finding bordering countries for a given country and get a lost of border country objects -
package com.advisory.pic.etl.claim.standardize;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Test {
public static void main(String[] args) {
}
public void workOnCountries(){
List<Country> countries = Arrays.asList(new Country("United States","USA",Arrays.asList("MXO","CDA")),
new Country("Mexico","MXO",Arrays.asList("USA","CLB")),
new Country("Colombia","CLB",Arrays.asList("MXO","VNZ")),
new Country("Canada","CNA",Arrays.asList("USA")));
//get list of neighbouring countries for USA
//first find USA in the list of countries
Country country = null;
for(Country c : countries){
if(c.alpha3Code.equalsIgnoreCase("USA")){
country = c;
}
}
//find border countries
List<String> b = country.borders;
//get border contries from main country list
List<Country> borderCountries = countries.stream().filter(c -> b.contains(c)).collect(Collectors.toList());
}
private class Country{
Country(String name, String alpha3Code, List<String> borders){
this.name = name;
this.alpha3Code = alpha3Code;
this.borders = borders;
}
private String name;
private String alpha3Code;
private List<String> borders = null;
}
}
if you want to pass array of objects to another screen you can use serialize in bundle
mCountryAdapter.setiOnItemClickListener(new CountryAdapter.OnItemClickListener() {
#Override
public void onItemClick(int position, List<String> borderCountries) {
Bundle bundle=new Bundle();
bundle.putSerializable("list",(ArrayList<String>) borderCountries);
// then you can add bundle to intent if you navigate activity or navigate
//fragment set this bundle
Log.d("myDebug", "onItemClick: " + position + " " + borderCountries);
}
});
I am very new to android and developing an app which will fetch some data from Firebase realtime database and show data on UI. but whenever app is loaded just nothing happened. In the Logcat window it is continuously
showing:
D/KeyguardUpdateMonitor: received broadcast
android.intent.action.BATTERY_CHANGED
D/KeyguardUpdateMonitor: handleBatteryUpdate
I/BatteryInfoReceiver: ACTION_BATTERY_CHANGED
W/QCNEJ: |CORE| CNE received unexpected action:
android.intent.action.BATTERY_CHANGED
i have also tried to search it out but can't understand..
just want to know
what is the mean of this
"android.intent.action.BATTERY_CHANGED"
and why its not showing any data on UI.
my firebase realtime database rules (read/write) are set to true. because i am just trying something..
is there any problem with permissions or manifest file? because i
don't have included any of the permissions in app..
i am using my redmi note 4 for testing app.
code for the app is here..
Model class.
public class ad {
private String adImage, SellerID, price, location, adTitle, adDescription;
public ad(){
}
public ad(String adImage, String seller, String price, String location, String adTitle, String description) {
this.adImage = adImage;
this.SellerID = seller;
this.price = price;
this.location = location;
this.adTitle = adTitle;
this.adDescription = description;
}
public String getAdImage() {
return adImage;
}
public void setAdImage(String adImage) {
this.adImage = adImage;
}
public String getSellerID() {
return SellerID;
}
public void setSellerID(String seller) {
this.SellerID = seller;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getAdTitle() {
return adTitle;
}
public void setAdTitle(String adTitle) {
this.adTitle = adTitle;
}
public String getAdDescription() {
return adDescription;
}
public void setAdDescription(String adDescription) {
this.adDescription = adDescription;
}
}
my adsViewHolder class
public class adsViewHolder extends RecyclerView.ViewHolder {
public ImageView ad_image ;
public TextView ad_title ;
public TextView ad_price ;
public TextView ad_location;
public adsViewHolder(#NonNull View itemView) {
super(itemView);
ad_image = (ImageView)itemView.findViewById(R.id.defPic);
ad_title = (TextView)itemView.findViewById(R.id.adTitle);
ad_price = (TextView)itemView.findViewById(R.id.adPrice);
ad_location = (TextView)itemView.findViewById(R.id.AdCityName);
}
}
my AdsProfile Activity code for fetching and shwoing data on ui.
public class AdsProfile extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
private RecyclerView AdsListRecyclerView;
private DatabaseReference mRef;
FirebaseRecyclerOptions<ad> options;
FirebaseRecyclerAdapter<ad, adsViewHolder> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ads_profile);
AdsListRecyclerView = (RecyclerView)findViewById(R.id.Ads_Display_Recycler_View);
AdsListRecyclerView.setHasFixedSize(true);
mRef = FirebaseDatabase.getInstance().getReference("ads");
options = new FirebaseRecyclerOptions.Builder<ad>()
.setQuery(mRef, ad.class).build();
adapter = new FirebaseRecyclerAdapter<ad, adsViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull adsViewHolder holder, int position, #NonNull ad model) {
holder.ad_title.setText(model.getAdTitle());
holder.ad_price.setText(model.getPrice());
holder.ad_location.setText(model.getLocation());
}
#NonNull
#Override
public adsViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.ad_layout,viewGroup,false);
return new adsViewHolder(view);
}
};
AdsListRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
adapter.startListening();
AdsListRecyclerView.setAdapter(adapter);
}
}
I’ve been trying to get recycler view working with retrofit. I seem to be pulling in the JSON fine from within getRecipes() method, and my logs are showing me that the some data is there.
However, when I call my getRecipes() method from onCreate(), something seems to be going wrong. When I check to see if my recipeList array contains my JSON results within onCreate, it is telling me it is empty. Why is it doing this if my logs within my getRecipes() method are showing me that data is there...?
Not sure if it is an issue with my recycler view or what I am doing with retrofit, or something else. Been trying for days to figure out, so any advice would be greatly appreciated.
JSON
https://d17h27t6h515a5.cloudfront.net/topher/2017/May/59121517_baking/baking.json
public class ItemListActivity extends AppCompatActivity {
private boolean mTwoPane;
public static final String LOG_TAG = "myLogs";
public static List<Recipe> recipeList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getRecipes();
setContentView(R.layout.activity_item_list);
getRecipes();
//Logging to check that recipeList contains data
if(recipeList.isEmpty()){
Log.d(LOG_TAG, "Is empty");
}else {
Log.d(LOG_TAG, "Is not empty");
}
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setTitle(getTitle());
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.item_list);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
SimpleItemRecyclerViewAdapter simpleItemRecyclerViewAdapter = new SimpleItemRecyclerViewAdapter(recipeList);
recyclerView.setAdapter(simpleItemRecyclerViewAdapter);
if (findViewById(R.id.item_detail_container) != null) {
mTwoPane = true;
}
}
public void getRecipes(){
String ROOT_URL = "https://d17h27t6h515a5.cloudfront.net/topher/2017/May/59121517_baking/";
Retrofit RETROFIT = new Retrofit.Builder()
.baseUrl(ROOT_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RecipeService service = RETROFIT.create(RecipeService.class);
Call<List<Recipe>> call = service.getMyJson();
call.enqueue(new Callback<List<Recipe>>() {
#Override
public void onResponse(Call<List<Recipe>> call, Response<List<Recipe>> response) {
Log.d(LOG_TAG, "Got here");
if (!response.isSuccessful()) {
Log.d(LOG_TAG, "No Success");
}
Log.d(LOG_TAG, "Got here");
recipeList = response.body();
//Logging to check data is there
Log.v(LOG_TAG, "LOGS" + recipeList.size());
for (int i = 0; i < recipeList.size(); i++) {
String newString = recipeList.get(i).getName();
Ingredients[] ingredients = recipeList.get(i).getIngredients();
for(int j = 0; j < ingredients.length; j++){
Log.d(LOG_TAG, ingredients[j].getIngredient());
}
Steps[] steps = recipeList.get(i).getSteps();
for(int k = 0; k < steps.length; k++){
Log.d(LOG_TAG, steps[k].getDescription());
}
Log.d(LOG_TAG, newString);
}
}
#Override
public void onFailure(Call<List<Recipe>> call, Throwable t) {
Log.e("getRecipes throwable: ", t.getMessage());
t.printStackTrace();
}
});
}
public class SimpleItemRecyclerViewAdapter
extends RecyclerView.Adapter<SimpleItemRecyclerViewAdapter.ViewHolder> {
private final List<Recipe> mValues;
public SimpleItemRecyclerViewAdapter(List<Recipe> items) {
mValues = items;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_list_content, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.mItem = mValues.get(position);
holder.mContentView.setText(mValues.get(position).getName());
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mTwoPane) {
Bundle arguments = new Bundle();
arguments.putString(ItemDetailFragment.ARG_ITEM_ID, holder.mItem.getId());
ItemDetailFragment fragment = new ItemDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.item_detail_container, fragment)
.commit();
} else {
Context context = v.getContext();
Intent intent = new Intent(context, ItemDetailActivity.class);
intent.putExtra(ItemDetailFragment.ARG_ITEM_ID, holder.mItem.getId());
context.startActivity(intent);
}
}
});
}
#Override
public int getItemCount() {
return mValues.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public View mView;
public TextView mContentView;
public Recipe mItem;
public ViewHolder(View view) {
super(view);
mView = view;
mContentView = (TextView) view.findViewById(R.id.content);
}
#Override
public String toString() {
return super.toString() + " '" + mContentView.getText() + "'";
}
}
}
RecipeService
public interface RecipeService {
#GET("baking.json")
Call<List<Recipe>> getMyJson();}
Models
Recipe
public class Recipe{
private Ingredients[] ingredients;
private String id;
private String servings;
private String name;
private String image;
private Steps[] steps;
public Ingredients[] getIngredients ()
{
return ingredients;
}
public void setIngredients (Ingredients[] ingredients)
{
this.ingredients = ingredients;
}
public String getId ()
{
return id;
}
public void setId (String id)
{
this.id = id;
}
public String getServings ()
{
return servings;
}
public void setServings (String servings)
{
this.servings = servings;
}
public String getName ()
{
return name;
}
public void setName (String name)
{
this.name = name;
}
public String getImage ()
{
return image;
}
public void setImage (String image)
{
this.image = image;
}
public Steps[] getSteps ()
{
return steps;
}
public void setSteps (Steps[] steps)
{
this.steps = steps;
}
#Override
public String toString()
{
return "[ingredients = "+ingredients+", id = "+id+", servings = "+servings+", name = "+name+", image = "+image+", steps = "+steps+"]";
}}
Ingredients
public class Ingredients{
private String measure;
private String ingredient;
private String quantity;
public String getMeasure ()
{
return measure;
}
public void setMeasure (String measure)
{
this.measure = measure;
}
public String getIngredient ()
{
return ingredient;
}
public void setIngredient (String ingredient)
{
this.ingredient = ingredient;
}
public String getQuantity ()
{
return quantity;
}
public void setQuantity (String quantity)
{
this.quantity = quantity;
}
#Override
public String toString()
{
return "[measure = "+measure+", ingredient = "+ingredient+", quantity = "+quantity+"]";
}}
Steps
public class Steps{
private String id;
private String shortDescription;
private String description;
private String videoURL;
private String thumbnailURL;
public String getId ()
{
return id;
}
public void setId (String id)
{
this.id = id;
}
public String getShortDescription ()
{
return shortDescription;
}
public void setShortDescription (String shortDescription)
{
this.shortDescription = shortDescription;
}
public String getDescription ()
{
return description;
}
public void setDescription (String description)
{
this.description = description;
}
public String getVideoURL ()
{
return videoURL;
}
public void setVideoURL (String videoURL)
{
this.videoURL = videoURL;
}
public String getThumbnailURL ()
{
return thumbnailURL;
}
public void setThumbnailURL (String thumbnailURL)
{
this.thumbnailURL = thumbnailURL;
}
#Override
public String toString()
{
return "[id = "+id+", shortDescription = "+shortDescription+", description = "+description+", videoURL = "+videoURL+", thumbnailURL = "+thumbnailURL+"]";
}}
Logs
https://gist.github.com/2triggers/12b6eeb32ed8909ab50bbadd4742d7f7
this will be empty always because this line will execute before getting the response from a server.
if(recipeList.isEmpty()){
Log.d(LOG_TAG, "Is empty");
}else {
Log.d(LOG_TAG, "Is not empty");
}
Better call this after this line recipeList = response.body();
SimpleItemRecyclerViewAdapter simpleItemRecyclerViewAdapter = new SimpleItemRecyclerViewAdapter(recipeList);
recyclerView.setAdapter(simpleItemRecyclerViewAdapter);
if (findViewById(R.id.item_detail_container) != null) {
mTwoPane = true;
}
it is because you are sending the recipelist into the adapter before even it is populated , after you are sending the recipelist into the adapter which is empty you are populating your recipelist from getRecipes method, you might be wondering you have declared the getRecipes method before even you are assigning the recipelist to adapter so how come it is empty, yea but the fact is your getRecipes work on background thread so even before your recipelist gets populated your adapter assignment takes place on the main thread so you are basically assigning the empty list, one thing you can do is notify when the adapter when the data changes or when the the recipelist is filled with data that is from within the getRecipe method.
when you assign the recipelist = response.body right after this you can notify the adapter
or move this two lines
SimpleItemRecyclerViewAdapter simpleItemRecyclerViewAdapter = new SimpleItemRecyclerViewAdapter(recipeList);
recyclerView.setAdapter(simpleItemRecyclerViewAdapter);
right after the
recipelist = response.body;
in getRecipes method
Try create the Constructor with all atributes from your Recipe.class
Like:
public Ingredients(String measure, String ingredients, String quantity ){
this.measure = measure;
this.ingredients = ingredients;
this.quantity = quantity
}
Do same in all class where make up your object of list.
I am getting json values from volley post request. I am adding those values to list using setter method. When i am retrieving values in adapter onBindViewholder() method and displaying it in a recyclerview result is not getting displayed as expected:
Below code refers to adding values to list from volley request and response in MainActivity.java:
private ProductsPojo pojo;
public static ProductsAdapter productsAdapter;
private List<ProductsPojo> pojoList;
pojo = new ProductsPojo();
pojoList = new ArrayList<>();
StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// Log.d("Appet8","Products response:"+response.toString());
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray products = jsonObject.getJSONArray("products");
for (int i=0;i<products.length();i++) {
JSONObject product_object = products.getJSONObject(i);
String name = product_object.getString("name");
String price = product_object.getString("price");
String product_id = product_object.getString("id");
String sessionname = product_object.getString("sessionname");
String image = product_object.getString("image");
String categoryname = product_object.getString("categoryname");
pojo.setName(product_object.getString("name"));
pojo.setImage(product_object.getString("image"));
pojoList.add(pojo);
}
productsAdapter = new ProductsAdapter(pojoList,getApplicationContext());
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// Toast.makeText(getApplicationContext(),error.getMessage(), Toast.LENGTH_LONG).show();
}
}) {
#Override
protected Map<String, String> getParams() {
// Posting parameters to login url
Map<String, String> params = new HashMap<String, String>();
params.put("customer_id", customer_id);
return params;
}
};
AppController.getInstance().addToRequestQueue(request,tag_request);
Below code refers to setting adapter to recyclerview in a ProductFragment.java:
private GridLayoutManager layoutManager;
private RecyclerView recyclerView;
recyclerView = (RecyclerView) view.findViewById(R.id.productList);
recyclerView.setHasFixedSize(true);
layoutManager = new GridLayoutManager(getActivity().getApplicationContext(),3);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(MainActivity.productsAdapter);
Below code refers to adapter class which displays values, ProductsAdapter.java:
public class ProductsAdapter extends RecyclerView.Adapter<ProductsAdapter.ProductsViewHolder> {
private List<ProductsPojo> productList;
private Context context;
public ProductsAdapter(List<ProductsPojo> productList,Context context) {
this.productList=productList;
this.context = context;
}
#Override
public ProductsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.
from(parent.getContext()).
inflate(R.layout.products_list, parent, false);
ProductsViewHolder holder = new ProductsViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(final ProductsViewHolder holder,final int position) {
final ProductsPojo pojo = productList.get(position);
Log.d("Appet8","Name:"+pojo.getName());
holder.vTitle.setText(pojo.getName());
holder.vTitle.setTypeface(MainActivity.font);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
pojo.setSelected(!pojo.isSelected());
holder.itemView.setBackgroundColor(pojo.isSelected() ? Color.parseColor("#4D79CF08") : Color.parseColor("#2D6F6F6F"));
if(pojo.isSelected()) {
holder.selected.setVisibility(View.VISIBLE);
} else if(!pojo.isSelected()) {
holder.selected.setVisibility(View.GONE);
}
}
});
}
#Override
public int getItemCount() {
return productList.size();
}
public static class ProductsViewHolder extends RecyclerView.ViewHolder {
protected TextView vTitle;
protected ImageView image,selected;
protected CardView product_card;
public ProductsViewHolder(View v) {
super(v);
vTitle = (TextView) v.findViewById(R.id.title);
image = (ImageView) v.findViewById(R.id.product);
product_card = (CardView) v.findViewById(R.id.product_card);
selected = (ImageView) v.findViewById(R.id.selected);
}
}
}
This is the response that i get from volley request:
{
"products":[
{
"name":"Idli",
"price":"120",
"id":"Fi2mYuQA",
"sessionname":"Breakfast",
"image":"VCYwmSae2BShoshone_Falls-1200px.jpeg",
"categoryname":"Veg"
},
{
"name":"Meals123",
"price":"200",
"id":"bmF8Is1Y",
"sessionname":"Dinner",
"image":"sIe8JBFzaRstock-photo-115193575.jpg",
"categoryname":"Non Veg"
},
{
"name":"Dosa",
"price":"100",
"id":"e9sWHV4A",
"sessionname":"Breakfast",
"image":"j8nu4GpVa7Shoshone_Falls-1200px.jpeg",
"categoryname":"Veg"
},
{
"name":"Coca",
"price":"40",
"id":"0oJDfdCz",
"sessionname":"Cold Drinks",
"image":"LrkS8QpAs7Shoshone_Falls-1200px.jpeg",
"categoryname":"Veg"
},
{
"name":"ICe",
"price":"100",
"id":"2ykEgtSs",
"sessionname":null,
"image":"KtPX9C26oRShoshone_Falls-1200px.jpeg",
"categoryname":"Veg"
}
]
}
This is the output i am getting. Item names are repeated.
Below code Refers to ProductsPojo.java:
public class ProductsPojo {
public String name;
public String image;
private boolean isSelected = false;
public void setName(String name) {
this.name = name;
}
public void setImage(String image) {
this.image = image;
}
public String getName() {
return name;
}
public String getImage() {
return image;
}
public void setSelected(boolean selected) {
isSelected = selected;
}
public boolean isSelected() {
return isSelected;
}
}
Looks to me like you only ever create one ProductsPojo instance, here:
pojo = new ProductsPojo();
And then in your loop you keep modifying this one instance, and then adding it to the list again and again. This way you'd end up with the same item (the last one) in your list as many times as the number of objects you got in the response.
What you wanted to do was probably to create a new ProductsPojo at the beginning of the for loop every time instead, like this:
for (int i=0;i<products.length();i++) {
ProductsPojo pojo = new ProductsPojo();
JSONObject product_object = products.getJSONObject(i);
String name = product_object.getString("name");
String price = product_object.getString("price");
String product_id = product_object.getString("id");
String sessionname = product_object.getString("sessionname");
String image = product_object.getString("image");
String categoryname = product_object.getString("categoryname");
pojo.setName(product_object.getString("name"));
pojo.setImage(product_object.getString("image"));
pojoList.add(pojo);
}
Im having an issue with getting data that is obtained when my listadapter is set to my listview. Im trying to get this data in onItemClick so that i can put it into my intent extra's for my other activity to obtain.
The Problem
Currently i've created null string variables and then in my adapter assigning the strings with the desired text by methods within my model. However the problem im having is that the text that is being pulled is not the correct text for the position that onitemclick was called for.
Here some code...
XMLParseActivity
public class XMLParseActivity extends Activity implements AdapterView.OnItemClickListener {
private ListView mIssueListView;
private IssueParser mIssueParser;
private List<IssueFeed> mIssueList;
private IssueAdapter mIssueAdapter;
private String result_connectedtype = "";
private String result_symptom = "";
private String result_problem = "";
private String result_solution = "";
private String result_comments = "";
...
public class IssueAdapter extends ArrayAdapter<IssueFeed> {
public List<IssueFeed> issueFeedList;
public IssueAdapter(Context context, int textViewResourceId, List<IssueFeed> issueFeedList) {
super(context, textViewResourceId, issueFeedList);
this.issueFeedList = issueFeedList;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
IssueHolder issueHolder = null;
if (convertView == null) {
view = View.inflate(XMLParseActivity.this, R.layout.issue_list_item, null);
issueHolder = new IssueHolder();
issueHolder.issueConnectedType = (TextView) view.findViewById(R.id.result_connected_type);
issueHolder.issueSymptomView = (TextView) view.findViewById(R.id.result_symptom);
view.setTag(issueHolder);
} else {
issueHolder = (IssueHolder) view.getTag();
}
IssueFeed issueFeed = issueFeedList.get(position);
issueHolder.issueConnectedType.setText(issueFeed.getConnected_type());
issueHolder.issueSymptomView.setText(issueFeed.getSymptom());
//THE DATA I WANT TO USE IN MY INTENT
result_solution = issueFeed.getSolution();
result_comments = issueFeed.getComments();
result_connectedtype = issueFeed.getConnected_type();
result_problem = issueFeed.getProblem();
result_symptom = issueFeed.getSymptom();
return view;
}
}
static class IssueHolder {
public TextView issueSymptomView;
public TextView issueConnectedType;
}
#Override
public void onItemClick(AdapterView<?> adapterView, View v, int position, long id) {
//Put the strings in intent extra
Intent intent = new Intent(this, SpecificIssueActivity.class);
intent.putExtra("symptom", result_symptom);
intent.putExtra("problem", result_problem);
intent.putExtra("solution", result_solution);
intent.putExtra("comments", result_comments);
intent.putExtra("connectedtype", result_connectedtype);
startActivity(intent);
}
The listAdapter is set in a asynctask in the below code
public class DoLocalParse extends AsyncTask<String, Void, List<IssueFeed>> {
ProgressDialog prog;
String jsonStr = null;
Handler innerHandler;
#Override
protected void onPreExecute() {
prog = new ProgressDialog(XMLParseActivity.this);
prog.setMessage("Loading....");
prog.show();
}
#Override
protected List<IssueFeed> doInBackground(String... params) {
mIssueParser = new IssueParser(null);
mIssueList = mIssueParser.parseLocally(params[0]);
return mIssueList;
}
#Override
protected void onPostExecute(List<IssueFeed> result) {
prog.dismiss();
runOnUiThread(new Runnable() {
#Override
public void run() {
mIssueAdapter = new IssueAdapter(XMLParseActivity.this, R.layout.issue_list_item,
mIssueList);
int count = mIssueAdapter.getCount();
if (count != 0 && mIssueAdapter != null) {
mIssueListView.setAdapter(mIssueAdapter);
}
}
});
}
}
And my model IssueFeed looks like this
public class IssueFeed implements Serializable {
private String connected_type;
private String symptom;
private String problem;
private String solution;
private String comments;
public IssueFeed() {
}
public IssueFeed(String connected_type, String symptom, String problem, String solution, String comments) {
this.connected_type = connected_type;
this.symptom = symptom;
this.problem = problem;
this.solution = solution;
this.comments = comments;
}
public String getConnected_type() {
return connected_type;
}
public String getSymptom() {
return symptom;
}
public String getProblem() {
return problem;
}
public String getSolution() {
return solution;
}
public String getComments() {
return comments;
}
public void setConnected_type(String connected_type) {
this.connected_type = connected_type;
}
public void setSymptom(String symptom) {
this.symptom = symptom;
}
public void setProblem(String problem) {
this.problem = problem;
}
public void setSolution(String solution) {
this.solution = solution;
}
public void setComments(String comments) {
this.comments = comments;
}
}
I have solve the issue by getting the data from some simple methods in my model to obtain the values.