I am getting some data from server in json format. I have a model class where I got all data from server and I put all data in a Array List. Now I am not able to get data in recyclerView.
MainActivity
public CopyOnWriteArrayList<PrisonerModel> inside1
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerViewInside = findViewById(R.id.rv);
signature_calculation_prisonerList();
new PrisonerListAsyncTask().execute(NetworkUtils.PRISONER_LIST, ctimestamp,
cnonce, cappkey, csign);
inside1 = new CopyOnWriteArrayList<>();
MyAdapter myAdapter = new MyAdapter(inside1, this, this);
recyclerViewInside.setAdapter(myAdapter);
}
Model.java file
public class PrisonerModel {
private String name;
private int image;
private int total_prisoner;
private int outside;
private int inside;
private String imageUri;
private String device;
public PrisonerModel() {
}
public PrisonerModel(String name, int image) {
this.name = name;
this.image = image;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getImage() {
return image;
}
public void setImage(int image) {
this.image = image;
}
public int getTotal_prisoner() {
return total_prisoner;
}
public int getOutside() {
return outside;
}
public int getInside() {
return inside;
}
public String getImageUri() {
return imageUri;
}
public String getDevice() {
return device;
}
public static PrisonerModel fromJson(JSONObject jsonObject)
{
PrisonerModel pm1 = new PrisonerModel();
MainActivity ma = new MainActivity();
try {
pm1.total_prisoner = jsonObject.getInt("total");
Log.e("total: ", String.valueOf(pm1.getTotal_prisoner()));
JSONArray jsonArray = jsonObject.getJSONArray("list");
ma.inside1 = pm1.fromJson(jsonArray);
Log.e("inside: ", String.valueOf(ma.inside1.get(0).getName()));
pm1.inside = pm1.x;
pm1.outside = pm1.getTotal_prisoner() - pm1.x;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
return pm1;
}
I am getting data of inside1 in this model class but when I use Log.e("") in Main Activity it throw error "ArrayOutOfBoundIndex"
could you help me where am i doing mistake?
Related
I would like to call the value of the String streamingLink to
String path1 ="xxxxx"; on MoviePlayerActivity.class (mentioned below)
Instead of xxxx, I need it to be the movie URL
Also, each movie has different URL stored inside an Array of List in DataSources.class
public class Movie {
private String title;
private String description;
private int thumbnail;
private int coverPhoto;
private String imdb;
private String rt;
private String streamingLink;
//Cast Initializing
private int cast1;
private int cast2;
private int cast3;
private String actor1;
private String actor2;
private String actor3;
public Movie(String title, int thumbnail, int coverPhoto, String actor1, int cast1, String actor2, int cast2, String actor3, int cast3, String streamingLink, String imdb, String rt, String description) {
this.title = title;
this.thumbnail = thumbnail;
this.coverPhoto = coverPhoto;
this.description =description;
this.imdb = imdb;
this.rt = rt;
this.streamingLink = streamingLink;
// Cast
this.cast1 = cast1;
this.cast2 = cast2;
this.cast3 = cast3;
this.actor1 = actor1;
this.actor2 = actor2;
this.actor3 = actor3;
}
public int getCoverPhoto() {
return coverPhoto;
}
public String getTitle() {
return title;
}
public String getDescription() {
return description;
}
public int getThumbnail() {
return thumbnail;
}
public String getImdb() {
return imdb;
}
public String getRt() {
return rt;
}
//Cast get activity
public int getCast1() {
return cast1;
}
public int getCast2() {
return cast2;
}
public int getCast3() {
return cast3;
}
public String getActor1() {
return actor1;
}
public String getActor2() {
return actor2;
}
public String getActor3() {
return actor3;
}
public String getStreamingLink() {
return streamingLink;
}
public void setTitle(String title) {
this.title = title;
}
public void setCoverPhoto(int coverPhoto) {
this.coverPhoto = coverPhoto;
}
public void setDescription(String description) {
this.description = description;
}
public void setThumbnail(int thumbnail) {
this.thumbnail = thumbnail;
}
public void setImdb(String imdb) {
this.imdb = imdb;
}
public void setRt(String rt) {
this.rt = rt;
}
public void setStreamingLink(String streamingLink) {
this.streamingLink = streamingLink;
}
//Cast set activity
public void setCast1(int cast1) {
this.cast1 = cast1;
}
public void setActor1(String actor1) {
this.actor1 = actor1;
}
public void setCast2(int cast2) {
this.cast2 = cast2;
}
public void setActor2(String actor2) {
this.actor2 = actor2;
}
public void setCast3(int cast3) {
this.cast3 = cast3;
}
public void setActor3(String actor3) {
this.actor3 = actor3;
}
}
MoviePlayerActivity:
public class MoviePlayerActivity extends AppCompatActivity {
private PlayerView playerView;
FloatingActionButton play_fab;
private SimpleExoPlayer simpleExoPlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
setFullScreen();
setContentView( R.layout.activity_movie_player );
hideActionbar();
iniExoPlayer();
}
private void hideActionbar() {
getSupportActionBar().hide();
}
private void setFullScreen() {
requestWindowFeature( Window.FEATURE_NO_TITLE );
getWindow().setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN );
}
private void iniExoPlayer() {
playerView=findViewById( R.id.movie_exo_player );
simpleExoPlayer = ExoPlayerFactory.newSimpleInstance( this );
playerView.setPlayer( simpleExoPlayer );
String path1 ="xxxxx";
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory( this,
Util.getUserAgent(this,"appname"));
MediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory )
.createMediaSource( Uri.parse( path1) );
simpleExoPlayer.prepare( videoSource );
simpleExoPlayer.setPlayWhenReady( true );
}
#Override
protected void onDestroy() {
super.onDestroy();
simpleExoPlayer.release();
}
}
Here's how the array looks like
this is class DataSource
public static List getEnglishMovies(){
List<Movie> lstMovies = new ArrayList<>();
lstMovies.add( new Movie( "Avengers: Endgame" , R.drawable.avgendgame, R.drawable.avgendgamecp,"Chris Hemsworth",R.drawable.chrishemsworth,"Robert Downey Jr.",R.drawable.downeyjr,"Chris Hemswoth",R.drawable.chrishemsworth,"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4","8.4","NA","After the devastating events of Avengers: Infinity War (2018), the universe is in ruins. With the help of remaining allies, the Avengers assemble once more in order to reverse Thanos' actions and restore balance to the universe.") );
lstMovies.add( new Movie( "Extraction" ,R.drawable.extraction, R.drawable.extractioncp,"Chris Hemswoth",R.drawable.chrishemsworth,"Chris Hemswoth",R.drawable.chrishemsworth,"Chris Hemswoth",R.drawable.chrishemsworth,"http://168.61.51.210/movies/Extraction.mp4","6.8","68%","Tyler Rake, a fearless black market mercenary, embarks on the most deadly extraction of his career when he's enlisted to rescue the kidnapped son of an imprisoned international crime lord.") );
lstMovies.add( new Movie( "The Call Of The Wild" ,R.drawable.thecallofthewildjpg,R.drawable.thecallofthewildcp,"Chris Hemswoth",R.drawable.chrishemsworth,"Chris Hemswoth",R.drawable.chrishemsworth,"Chris Hemswoth",R.drawable.chrishemsworth,"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4","6.8","62%", "Adapted from the beloved literary classic, THE CALL OF THE WILD vividly brings to the screen the story of Buck, a big-hearted dog whose blissful domestic life is turned upside down when he is suddenly uprooted from his California home and transplanted to the exotic wilds of the Alaskan Yukon during the Gold Rush of the 1890s. As the newest rookie on a mail delivery dog sled team--and later its leader--Buck experiences the adventure of a lifetime, ultimately finding his true place in the world and becoming his own master.") );
lstMovies.add( new Movie( "Do Little" ,R.drawable.dolittle, R.drawable.dolittlecp,"Chris Hemswoth",R.drawable.chrishemsworth,"Chris Hemswoth",R.drawable.chrishemsworth,"Chris Hemswoth",R.drawable.chrishemsworth,"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4","5.6","NA","A physician who can talk to animals embarks on an adventure to find a legendary island with a young apprentice and a crew of strange pets.") );
return lstMovies;
}
I have a FirebaseRecyclerAdapter fetching data from the firebase database but when I am trying to access firebase data the getter method of the POJO returns null. I am able to get the database reference key.
final Query beveragesQuery = mDatabaseReference.child(FirebaseValues.PRODUCTS)
.child(FirebaseValues.BEVERAGES);
FirebaseRecyclerOptions<GenericProductModel> beveragesOptions =
new FirebaseRecyclerOptions.Builder<GenericProductModel>()
.setQuery(beveragesQuery, GenericProductModel.class)
.build();
adapter = new FirebaseRecyclerAdapter<GenericProductModel, Combos.MovieViewHolder>(
beveragesOptions
) {
#NonNull
#Override
public Combos.MovieViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.cards_cardview_layout, parent, false);
return new Combos.MovieViewHolder(view);
}
#Override
protected void onBindViewHolder(#NonNull Combos.MovieViewHolder viewHolder, int position, #NonNull GenericProductModel model) {
Log.d(TAG, "Item received:"+getRef(position).getKey());
String json = new Gson().toJson(model);
Log.d(TAG, "Item received:"+ json);
Log.d(TAG, "Item received:"+ model.toString());
if (tv_no_item.getVisibility() == View.VISIBLE) {
tv_no_item.setVisibility(View.GONE);
}
Log.d(TAG, "card name:"+model.getCardname());
viewHolder.cardname.setText(model.getCardname());
viewHolder.cardprice.setText("₹ " + Float.toString(model.getCardprice()));
Picasso.get().load(model.getCardimage()).into(viewHolder.cardimage);
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Beverages.this, IndividualProduct.class);
intent.putExtra("product", getItem(position));
startActivity(intent);
}
});
}
#Override
public void onError(DatabaseError e) {
Log.e(TAG, "RV Adapter, Error occurred: " + e.getMessage());
}
};
mLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(mLayoutManager);
adapter.startListening();
mRecyclerView.setAdapter(adapter);
}
My POJO or model class is
public class GenericProductModel implements Serializable {
public int cardid;
public String cardname;
public String cardimage;
public String carddescription;
public float cardprice;
public GenericProductModel() {
}
public GenericProductModel(int cardid, String cardname, String cardimage, String carddescription, float cardprice) {
this.cardid = cardid;
this.cardname = cardname;
this.cardimage = cardimage;
this.carddescription = carddescription;
this.cardprice = cardprice;
}
public int getCardid() {
return cardid;
}
public String getCardname() {
return cardname;
}
public String getCardimage() {
return cardimage;
}
public String getCarddescription() {
return carddescription;
}
public float getCardprice() {
return cardprice;
}
public void setCardid(int cardid) {
this.cardid = cardid;
}
public void setCardname(String cardname) {
this.cardname = cardname;
}
public void setCardimage(String cardimage) {
this.cardimage = cardimage;
}
public void setCarddescription(String carddescription) {
this.carddescription = carddescription;
}
public void setCardprice(float cardprice) {
this.cardprice = cardprice;
}
}
I am implementing Serializable because I am sending this data as an intent to other activity.
Added some more log options for clearity
When I run the app the log output I am getting is:
03-17 15:05:55.200 4501-4501/com.vdeveloper.chaisutta D/BeveragesTAG: Item received, received:1
03-17 15:05:55.227 4501-4501/com.vdeveloper.chaisutta D/BeveragesTAG: Item received:{"a":0,"e":0.0}
03-17 15:05:55.227 4501-4501/com.vdeveloper.chaisutta D/BeveragesTAG: Item received:com.vdeveloper.chaisutta.b.a#63d3fc
03-17 15:05:55.227 4501-4501/com.vdeveloper.chaisutta D/BeveragesTAG: card name:null
Database Screenshot:
I have found a solution myself. The problem was with my POJO. As this project was on androidx I need to add the annotation "#Keep" to stop the compiler from removing methods which it thinks are redundant.
import java.io.Serializable;
import androidx.annotation.Keep;
#Keep
public class GenericProductModel implements Serializable {
public int cardid;
public String cardname;
public String cardimage;
public String carddescription;
public float cardprice;
public GenericProductModel() {
}
public GenericProductModel(int cardid, String cardname, String cardimage, String carddescription, float cardprice) {
this.cardid = cardid;
this.cardname = cardname;
this.cardimage = cardimage;
this.carddescription = carddescription;
this.cardprice = cardprice;
}
public int getCardid() {
return cardid;
}
public String getCardname() {
return cardname;
}
public String getCardimage() {
return cardimage;
}
public String getCarddescription() {
return carddescription;
}
public float getCardprice() {
return cardprice;
}
public void setCardid(int cardid) {
this.cardid = cardid;
}
public void setCardname(String cardname) {
this.cardname = cardname;
}
public void setCardimage(String cardimage) {
this.cardimage = cardimage;
}
public void setCarddescription(String carddescription) {
this.carddescription = carddescription;
}
public void setCardprice(float cardprice) {
this.cardprice = cardprice;
}
}
Thanks, everyone for helping
You are getting null because all your values are null since you are returning in each getter this.fieldName instead of the fieldName. To solve this, please change your getters to:
public int getCardid() {
return cardid;
}
public String getCardname() {
return cardname;
}
public String getCardimage() {
return cardimage;
}
public String getCarddescription() {
return carddescription;
}
public float getCardprice() {
return cardprice;
}
See, there is no this anymore.
I am developing the android app I want to save retrofit response into Realm and I want to use it when my app is offline and I have followed
link However when I run an app in offline mode it is not showing any data.
below IntroductionItem.java class where I have implement realm
public class IntroductionItem extends AppCompatActivity {
public RealmList<Introduction> introductionList;
public Context context;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.introduction);
Realm.init(IntroductionItem.this);
RealmConfiguration realmConfiguration = new RealmConfiguration.Builder().build();
final Realm realm = Realm.getInstance(realmConfiguration);
KitabInterface kitabInterface = ApiClient.getApiService();
Call<KitabSawti> call = kitabInterface.getIntroduction();
call.enqueue(new Callback<KitabSawti>() {
#Override
public void onResponse(Call<KitabSawti> call, Response<KitabSawti> response) {
introductionList = response.body().getIntroduction();
RecyclerView recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
recyclerView.setAdapter( new IntroductionAdapter(IntroductionItem.this, introductionList));
for(int i = 0; i < introductionList.size(); i++)
realm.beginTransaction();
Introduction introduction= realm.createObject(Introduction.class);
introduction.setImage(introductionList.get(0).getImage());
introduction.setIntroduction(introductionList.get(0).getIntroduction());
realm.commitTransaction();
recyclerView.setVisibility(View.VISIBLE);
// changes
// realm.close();
}
#Override
public void onFailure(Call<KitabSawti> call, Throwable t) {
}
});
}
}
Pojo: Introduction.java
public class Introduction extends RealmObject {
#SerializedName("image")
#Expose
private String image;
#SerializedName("introduction")
#Expose
private String introduction;
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getIntroduction() {
return introduction;
}
public void setIntroduction(String introduction) {
this.introduction = introduction;
}
}
Below KitabSawti Pojo class
public class KitabSawti extends RealmObject {
#SerializedName("Introduction")
#Expose
private RealmList<Introduction> introduction = null;
#SerializedName("Education")
#Expose
private RealmList<Education> education = null;
#SerializedName("Work")
#Expose
private RealmList<Work> work = null;
#SerializedName("Skills")
#Expose
private RealmList<Skill> skills = null;
#SerializedName("Contact")
#Expose
private RealmList<Contact> contact = null;
public RealmList<Introduction> getIntroduction() {
return introduction;
}
public void setIntroduction(RealmList<Introduction> introduction) {
this.introduction = introduction;
}
public RealmList<Education> getEducation() {
return education;
}
public void setEducation(RealmList<Education> education) {
this.education = education;
}
public RealmList<Work> getWork() {
return (RealmList<Work>) work;
}
public void setWork(RealmList<Work> work) {
this.work = work;
}
public RealmList<Skill> getSkills() {
return (RealmList<Skill>) skills;
}
public void setSkills(RealmList<Skill> skills) {
this.skills = skills;
}
public RealmList<Contact> getContact() {
return (RealmList<Contact>) contact;
}
public void setContact(RealmList<Contact> contact) {
this.contact = contact;
}
}
I'v tried to create a movies app so I create recycleview to display the poster in gridlayout using networking with api json data
now the app fetch the name of movies and it's popularity without problems but can't fetch the poster and when I debug the app I found the value of poster null when it comes to onbindviewholder why that?
this is the adapter of recycleview:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolder> {
ArrayList<MovieItem> mMoviesItems;
private Context context;
public RecyclerViewAdapter() {
}
class RecyclerViewHolder extends RecyclerView.ViewHolder {
public final TextView MoviePopularity;
public final ImageView MoviePoster;
public final TextView MovieName;
public RecyclerViewHolder(View view) {
super(view);
MoviePopularity = (TextView)itemView.findViewById(R.id.movie_popularity);
MoviePoster = (ImageView)itemView.findViewById(R.id.iv_item_movie);
MovieName = (TextView)itemView.findViewById(R.id.movie_name);
}
}
#Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
context = viewGroup.getContext();
int layoutIdForListItem = R.layout.movie_list_item;
LayoutInflater inflater = LayoutInflater.from(context);
boolean shouldAttachToParentImmediately = false;
View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
return new RecyclerViewHolder(view);
}
#Override
public void onBindViewHolder(RecyclerViewHolder holder, int position) {
holder.MoviePopularity.setText(String.valueOf(mMoviesItems.get(position).getPopularity()));
Picasso.with(this.context).load(mMoviesItems.get(position).getPhoto()).into(holder.MoviePoster);
holder.MovieName.setText(String.valueOf(mMoviesItems.get(position).getName()));
}
#Override
public int getItemCount() {
if (null == mMoviesItems)
return 0;
else {
return mMoviesItems.size();
}
}
public void setMovieData(ArrayList<MovieItem> movieData) {
mMoviesItems = movieData;
notifyDataSetChanged();
}
}
and this is the custom class:
public class MovieItem {
private double popularity;
private String photo;
private String name;
public MovieItem(double popularity, String poster_path, String original_title) {
this.popularity = popularity;
this.photo = poster_path;
this.name = original_title;
}
public double getPopularity() { return popularity; }
public String getPhoto() { return photo; }
public String getName() { return name; }
}
and this is the json class:
public final class OpenMovieJsonUtils {
public static ArrayList<MovieItem> getSimpleMovieStringsFromJson(Context context, String moviesJsonString)
throws JSONException {
final String RESULTS = "results";
final String POPULARITY = "popularity";
final String POSTER_PATH = "poster_path";
final String ORIGINAL_TITLE = "original_title";
ArrayList<MovieItem> parsedMovieData = new ArrayList<MovieItem>();
JSONObject moviesObject = new JSONObject(moviesJsonString);
JSONArray moviesArray = moviesObject.getJSONArray(RESULTS);
for (int i = 0; i < moviesArray.length(); i++) {
double popularity;
String poster_path;
String original_title;
moviesObject = moviesArray.getJSONObject(i);
popularity = moviesObject.getDouble(POPULARITY);
poster_path = moviesObject.getString(POSTER_PATH);
original_title = moviesObject.getString(ORIGINAL_TITLE);
parsedMovieData.add(new MovieItem(popularity, poster_path, original_title));
}
return parsedMovieData;
}
}
this is the networking class:
public final class NetworkUtils {
private static final String TAG = NetworkUtils.class.getSimpleName();
private static final String MOVIES_BASE_URL = "https://api.themoviedb.org/3/movie/";
private static final String MOVIES_URL = MOVIES_BASE_URL;
private static final String apiKey = "36666cbb5d7e20041e705d1b2c4e7a79";
final static String API_PARAM = "api_key";
public static URL buildUrl(String MoviesQuery) {
Uri builtUri = Uri.parse(MOVIES_URL).buildUpon()
.appendPath(MoviesQuery)
.appendQueryParameter(API_PARAM, apiKey)
.build();
URL url = null;
try {
url = new URL(builtUri.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
Log.v(TAG, "Built URI " + url);
return url;
}
public static String getResponseFromHttpUrl(URL url) throws IOException {
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = urlConnection.getInputStream();
Scanner scanner = new Scanner(in);
scanner.useDelimiter("\\A");
boolean hasInput = scanner.hasNext();
if (hasInput) {
return scanner.next();
} else {
return null;
}
} finally {
urlConnection.disconnect();
}
}
}
what's wrong with images so I get their values null instead of the popularity and name of movies works and not null
Your question is incomplete, doesn't specify the complete details about from where you are getting API response.
I could answer this question because I have just done this project in my ongoing Android Developer Nanodegree by Udacity.
Hopefully you are fetching the movie details from TMDB.
You should read the Project implementation guide thoroughly which says
You will need to append a base path ahead of this relative path to build the complete url you will need to fetch the image using Picasso
Following code will help you -
public class MovieItem {
private double popularity;
private String photo;
private String name;
public MovieItem(double popularity, String poster_path, String original_title) {
this.popularity = popularity;
this.photo = poster_path;
this.name = original_title;
}
public double getPopularity() { return popularity; }
public String getPhoto() { return photo; }
public String getName() { return name; }
public Uri getFullPosterPath() {
return Uri.parse("http://image.tmdb.org/t/p/")
.buildUpon()
.appendPath("w185")
.appendEncodedPath(getPhoto())
.build();
}
}
And in Adapter make this change -
#Override
public void onBindViewHolder(RecyclerViewHolder holder, int position) {
holder.MoviePopularity.setText(String.valueOf(mMoviesItems.get(position).getPopularity()));
Picasso.with(this.context).load(mMoviesItems.get(position).getFullPosterPath()).into(holder.MoviePoster);
holder.MovieName.setText(String.valueOf(mMoviesItems.get(position).getName()));
}
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.