Viewmodel null after initializing - java

after initializing the ViewModel i keep getting an error of null object reference , and i don't know why
import androidx.lifecycle.LiveData;
import androidx.lifecycle.ViewModel;
import com.example.foodapp.models.Recipe;
import com.example.foodapp.respositories.RecipeRepository;
public class RecipeViewModel extends ViewModel {
private String mRecipeId;
private RecipeRepository mRecipeRepository;
public RecipeViewModel() {
mRecipeRepository=RecipeRepository.getInstance();
}
public LiveData<Recipe>getRecipe(){
return mRecipeRepository.getRecipe();
}
public void searchRecipeById(String recipeId)
{ mRecipeId = recipeId;
mRecipeRepository.searchRecipeById(recipeId);
}
public String getViewModelRecipeId() {
return mRecipeId;
}
}
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.example.foodapp.models.Recipe;
import com.example.foodapp.viewmodels.RecipeViewModel;
public class RecipeActivity extends BaseActivity {
private static final String TAG = "RecipeActivity";
private AppCompatImageView mRecipeImage;
private TextView mRecipeTitle ,mRecipeRank;
private LinearLayout mRecipeIngredientsContainer;
private ScrollView mScrollView;
private RecipeViewModel mRecipeViewModel;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recipe);
mRecipeImage=findViewById(R.id.recipe_image);
mRecipeTitle=findViewById(R.id.recipe_title);
mRecipeRank=findViewById(R.id.recipe_social_score);
mRecipeIngredientsContainer=findViewById(R.id.ingredients_container);
mScrollView=findViewById(R.id.parent);
mRecipeViewModel=new ViewModelProvider(this).get(RecipeViewModel.class);
showProgressBar(true);
subscribeObserver();
getIncomingIntent();
}
private void getIncomingIntent(){
if(getIntent().hasExtra("recipe")){
Recipe recipe=getIntent().getParcelableExtra("recipe");
Log.d(TAG, "getIncomingIntent: "+recipe.getTitle());
mRecipeViewModel.searchRecipeById(recipe.getRecipeId());
}
}
private void subscribeObserver(){
mRecipeViewModel.getRecipe().observe(this, new Observer<Recipe>() {
#Override
public void onChanged(Recipe recipe) {
if(recipe!=null){
if(recipe.getRecipeId().equals(mRecipeViewModel.getViewModelRecipeId())){
setRecipeProperties(recipe);
}
}
}
});
}
private void setRecipeProperties(Recipe recipe){
if(recipe!=null){
RequestOptions requestOptions= new RequestOptions()
.placeholder(R.drawable.ic_launcher_background);
Glide.with(this).setDefaultRequestOptions(requestOptions)
.load(recipe.getImageUrl()).into(mRecipeImage);
mRecipeTitle.setText(recipe.getTitle());
mRecipeRank.setText(String.valueOf(recipe.getSocialUrl()));
mRecipeIngredientsContainer.removeAllViews();
for(String ingredients: recipe.getIngredients()){
TextView textView= new TextView(this);
textView.setText(ingredients);
textView.setTextSize(15);
textView.setLayoutParams(new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT
));
mRecipeIngredientsContainer.addView(textView);
}
}
showParent();
showProgressBar(false);
}
private void showParent(){
mScrollView.setVisibility(View.VISIBLE);
}
}
and this is the exception am getting:
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at com.example.foodapp.RecipeActivity$1.onChanged(RecipeActivity.java:63)
at com.example.foodapp.RecipeActivity$1.onChanged(RecipeActivity.java:57)
at androidx.lifecycle.LiveData.considerNotify(LiveData.java:133)
at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:151)
at androidx.lifecycle.LiveData.setValue(LiveData.java:309)
at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)..etc
the model class :
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Arrays;
public class Recipe implements {
private String title;
private String publisher;
private String imageUrl;
private String id;
private String [] ingredients;
private float socialUrl;
public Recipe() {
}
public Recipe(String title, String publisher, String image_url, String id,
String[] ingredients, float socialUrl) {
this.title = title;
this.publisher = publisher;
this.imageUrl = image_url;
this.id = id;
this.ingredients = ingredients;
this.socialUrl = socialUrl;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public String getRecipeId() {
return id;
}
public void setRecipeId(String id) {
this.id = id;
}
public String[] getIngredients() {
return ingredients;
}
public void setIngredients(String[] ingredients) {
this.ingredients = ingredients;
}
public float getSocialUrl() {
return socialUrl;
}
public void setSocialUrl(float socialUrl) {
this.socialUrl = socialUrl;
}
#Override
public String toString() {
return "Recipe{" +
"title='" + title + '\'' +
", publisher='" + publisher + '\'' +
", image_url='" + imageUrl + '\'' +
", recipe_id='" + id + '\'' +
", ingredients=" + Arrays.toString(ingredients) +
", social_rank=" + socialUrl +
'}';
}}
I've tried cleaning the project and invalidate and cache and even using the deprecated ViewModelProviders class ,
but all the same and nothing has changed

#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recipe);
mRecipeImage=findViewById(R.id.recipe_image);
mRecipeTitle=findViewById(R.id.recipe_title);
mRecipeRank=findViewById(R.id.recipe_social_score);
mRecipeIngredientsContainer=findViewById(R.id.ingredients_container);
mScrollView=findViewById(R.id.parent);
mRecipeViewModel=new ViewModelProvider(this).get(RecipeViewModel.class);
showProgressBar(true);
getIncomingIntent(); //this method needs to be called first
subscribeObserver(); // then this method.
}

Related

Can't pass null for argument 'pathString' in child() error

ModelOrderUser.java
package my.anupamroy.smartcanteenapp.models;
public class ModelOrderUser {
String orderId,orderTime,orderStatus,orderCost,orderBy,orderTo;
public ModelOrderUser(){
}
public ModelOrderUser(String orderId, String orderTime, String orderStatus, String orderCost, String orderBy, String orderTo) {
this.orderId = orderId;
this.orderTime = orderTime;
this.orderStatus = orderStatus;
this.orderCost = orderCost;
this.orderBy = orderBy;
this.orderTo = orderTo;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public String getOrderTime() {
return orderTime;
}
public void setOrderTime(String orderTime) {
this.orderTime = orderTime;
}
public String getOrderStatus() {
return orderStatus;
}
public void setOrderStatus(String orderStatus) {
this.orderStatus = orderStatus;
}
public String getOrderCost() {
return orderCost;
}
public void setOrderCost(String orderCost) {
this.orderCost = orderCost;
}
public String getOrderBy() {
return orderBy;
}
public void setOrderBy(String orderBy) {
this.orderBy = orderBy;
}
public String getOrderTo() {
return orderTo;
}
public void setOrderTo(String orderTo) {
this.orderTo = orderTo;
}
}
AdapterOrderUser.java
package my.anupamroy.smartcanteenapp.adapters;
import android.content.Context;
import android.text.Layout;
import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.Calendar;
import my.anupamroy.smartcanteenapp.R;
import my.anupamroy.smartcanteenapp.models.ModelOrderUser;
public class AdapterOrderUser extends RecyclerView.Adapter<AdapterOrderUser.HolderOrderUser>{
private Context context;
private ArrayList<ModelOrderUser> orderUserList;
public AdapterOrderUser(Context context, ArrayList<ModelOrderUser> orderUserList) {
this.context = context;
this.orderUserList = orderUserList;
}
#NonNull
#Override
public HolderOrderUser onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//inflate layout
View view = LayoutInflater.from(context).inflate(R.layout.row_order_user,parent,false);
return new HolderOrderUser(view);
}
#Override
public void onBindViewHolder(#NonNull HolderOrderUser holder, int position) {
//get data
ModelOrderUser modelOrderUser=orderUserList.get(position);
String orderId = modelOrderUser.getOrderId();
String orderBy = modelOrderUser.getOrderBy();
String orderCost = modelOrderUser.getOrderCost();
String orderStatus = modelOrderUser.getOrderStatus();
String orderTime = modelOrderUser.getOrderTime();
String orderTo = modelOrderUser.getOrderTo();
//get shop info
loadShopInfo(modelOrderUser,holder);
//set data
holder.amountTv.setText("Amount: ₹" +orderCost);
holder.statusTv.setText(orderStatus);
holder.orderIdTv.setText("OrderID:"+orderId);
// change order status text color
if(orderStatus.equals("In Progress")){
holder.statusTv.setTextColor(context.getResources().getColor(R.color.colorPrimary));
}
else if(orderStatus.equals("Completed")){
holder.statusTv.setTextColor(context.getResources().getColor(R.color.colorGreen));
}
else if(orderStatus.equals("Cancelled")){
holder.statusTv.setTextColor(context.getResources().getColor(R.color.colorRed));
}
//convert timestamp to proper format
Calendar calendar =Calendar.getInstance();
calendar.setTimeInMillis(Long.parseLong(orderTime));
String formatedDate= DateFormat.format("dd/MM/yyy",calendar).toString();
holder.dateTv.setText(formatedDate);
}
private void loadShopInfo(ModelOrderUser modelOrderUser, final HolderOrderUser holder) {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users");
ref.child(modelOrderUser.getOrderTo())
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String shopName =""+dataSnapshot.child("shopName").getValue();
holder.shopNameTv.setText(shopName);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
#Override
public int getItemCount() {
return orderUserList.size();
}
//view holder class
class HolderOrderUser extends RecyclerView.ViewHolder{
private TextView orderIdTv,dateTv,shopNameTv,amountTv,statusTv;
public HolderOrderUser(#NonNull View itemView) {
super(itemView);
//init views of layout
orderIdTv=itemView.findViewById(R.id.orderIdTv);
dateTv=itemView.findViewById(R.id.dateTv);
shopNameTv=itemView.findViewById(R.id.shopNameTv);
amountTv=itemView.findViewById(R.id.amountTv);
statusTv=itemView.findViewById(R.id.statusTv);
}
}
}
I am facing the following while executing don't know what is happening
java.lang.NullPointerException: Can't pass null for argument 'pathString' in child()
at com.google.firebase.database.DatabaseReference.child(DatabaseReference.java:96)
at my.anupamroy.smartcanteenapp.adapters.AdapterOrderUser.loadShopInfo(AdapterOrderUser.java:84)
at my.anupamroy.smartcanteenapp.adapters.AdapterOrderUser.onBindViewHolder(AdapterOrderUser.java:56)
at my.anupamroy.smartcanteenapp.adapters.AdapterOrderUser.onBindViewHolder(AdapterOrderUser.java:26)
Please help me out with this error
don't know why the code is throwing errors for me
please help me out
I am getting errors in lines number 84,56,26

App crashing when i hit a button that calls a function i made [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 1 year ago.
Improve this question
Ok, so I Am making a movie app and while doing so I came across this problem. I Have this function which when pressed will print out titles of some movies but when I try to run it I get this error message I'm getting the movies using TMDB API.
If you know how to fix it please tell me, Thanks!
java.lang.IllegalStateException: Could not execute method for android:onClick
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:414)
at android.view.View.performClick(View.java:7448)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
at android.view.View.performClickInternal(View.java:7425)
at android.view.View.access$3600(View.java:810)
at android.view.View$PerformClick.run(View.java:28305)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:409)
at android.view.View.performClick(View.java:7448) 
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119) 
at android.view.View.performClickInternal(View.java:7425) 
at android.view.View.access$3600(View.java:810) 
at android.view.View$PerformClick.run(View.java:28305) 
at android.os.Handler.handleCallback(Handler.java:938) 
at android.os.Handler.dispatchMessage(Handler.java:99) 
at android.os.Looper.loop(Looper.java:223) 
at android.app.ActivityThread.main(ActivityThread.java:7656) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 
Caused by: java.lang.IllegalArgumentException: Missing either #GET URL or #Url parameter.
for method MovieApi.searchMovie
at retrofit2.Utils.methodError(Utils.java:54)
at retrofit2.Utils.methodError(Utils.java:43)
at retrofit2.RequestFactory$Builder.build(RequestFactory.java:210)
at retrofit2.RequestFactory.parseAnnotations(RequestFactory.java:67)
at retrofit2.ServiceMethod.parseAnnotations(ServiceMethod.java:26)
at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:202)
at retrofit2.Retrofit$1.invoke(Retrofit.java:160)
at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
at $Proxy1.searchMovie(Unknown Source)
at com.example.watchitmovieapp.MainActivity.GetRetrofitResponse(MainActivity.java:44)
at com.example.watchitmovieapp.MainActivity.onButtonClicked(MainActivity.java:37)
Here is my code
Main Activity
package com.example.watchitmovieapp;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.example.watchitmovieapp.models.MovieModel;
import com.example.watchitmovieapp.request.Servicey;
import com.example.watchitmovieapp.response.MovieSearchResponse;
import com.example.watchitmovieapp.utils.Credentials;
import com.example.watchitmovieapp.utils.MovieApi;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class MainActivity extends AppCompatActivity {
Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = findViewById(R.id.button);
}
public void onButtonClicked(View view){
GetRetrofitResponse();
}
private void GetRetrofitResponse() {
MovieApi movieApi = Servicey.getMovieApi();
Call<MovieSearchResponse> responseCall = movieApi
.searchMovie(
Credentials.API_KEY,
"Jack Reacher",
"1");
responseCall.enqueue(new Callback<MovieSearchResponse>() {
#Override
public void onResponse(Call<MovieSearchResponse> call, Response<MovieSearchResponse> response) {
if (response.code() == 200){
//Log.v("Tag", "The response" + response.body().toString());
List<MovieModel> movies = new ArrayList<>(response.body().getMovies());
for (MovieModel movie: movies){
Log.v("Tag", "Name" + movie.getTitle());
}
}else{
try {
Log.v("Tag", "Error" + response.errorBody().string());
}catch (IOException e){
e.printStackTrace();
}
}
}
#Override
public void onFailure(Call<MovieSearchResponse> call, Throwable t) {
}
});
}
}
Servicey
package com.example.watchitmovieapp.request;
import com.example.watchitmovieapp.utils.Credentials;
import com.example.watchitmovieapp.utils.MovieApi;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.GET;
public class Servicey {
private static Retrofit.Builder retrofitBuilder =
new Retrofit.Builder()
.baseUrl(Credentials.BASE_URL)
.addConverterFactory(GsonConverterFactory.create());
private static Retrofit retrofit = retrofitBuilder.build();
private static MovieApi movieApi = retrofit.create(MovieApi.class);
public static MovieApi getMovieApi(){
return movieApi;
}
}
MovieSearchResponse
package com.example.watchitmovieapp.response;
import com.example.watchitmovieapp.models.MovieModel;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class MovieSearchResponse {
#SerializedName("total_results")
#Expose()
private int total_count;
#SerializedName("results")
#Expose()
private List<MovieModel> movies;
public int getTotal_count(){
return total_count;
}
public List<MovieModel> getMovies(){
return movies;
}
#Override
public String toString() {
return "MovieSearchResponse{" +
"total_count=" + total_count +
", movies=" + movies +
'}';
}
}
MovieApi
package com.example.watchitmovieapp.utils;
import android.graphics.Movie;
import com.example.watchitmovieapp.response.MovieSearchResponse;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface MovieApi {
// searching
#GET
Call<MovieSearchResponse> searchMovie(
#Query("key") String key,
#Query("query") String query,
#Query("page") String page
);
}
Movie Model
package com.example.watchitmovieapp.models;
import android.os.Parcel;
import android.os.Parcelable;
public class MovieModel implements Parcelable {
private String title;
private String poster_path;
private String release_date;
private int movie_id;
private float vote_average;
private String movie_overview;
//Constructor
public MovieModel(String title, String poster_path, String release_date, int movie_id, float vote_average, String movie_overview) {
this.title = title;
this.poster_path = poster_path;
this.release_date = release_date;
this.movie_id = movie_id;
this.vote_average = vote_average;
this.movie_overview = movie_overview;
}
//Getters
protected MovieModel(Parcel in) {
title = in.readString();
poster_path = in.readString();
release_date = in.readString();
movie_id = in.readInt();
vote_average = in.readFloat();
movie_overview = in.readString();
}
public static final Creator<MovieModel> CREATOR = new Creator<MovieModel>() {
#Override
public MovieModel createFromParcel(Parcel in) {
return new MovieModel(in);
}
#Override
public MovieModel[] newArray(int size) {
return new MovieModel[size];
}
};
public String getTitle() {
return title;
}
public String getPoster_path() {
return poster_path;
}
public String getRelease_date() {
return release_date;
}
public int getMovie_id() {
return movie_id;
}
public float getVote_average() {
return vote_average;
}
public String getMovie_overview() {
return movie_overview;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(title);
parcel.writeString(poster_path);
parcel.writeString(release_date);
parcel.writeInt(movie_id);
parcel.writeFloat(vote_average);
parcel.writeString(movie_overview);
}
}
You are missing URL(Request destination path) after #GET in yoursearchMovie() method in MovieApi interface
Example:
#GET("api/fruit/all")

JSON onResponse - List will not populate with data

I am getting a working app (kinda). It is meant to populate the screen from a request for JSON data. I thought what I have so far would work but I guess not.
onResponse does not seem to ever be called so the data is never assigned to a variable to be processed and I don't know how to fix this. Any and all help is very much appreciated.
Below is my relevant code:
My JSON data is:
{
"popular":[
{
"name":"Pizza",
"imageURL":"https://static4.depositphotos.com/1016418/315/i/600/depositphotos_3158962-stock-photo-pepperoni-pizza-isolated.jpg",
"rating":"4.8",
"deliveryTime":"45 min",
"deliveryCharges":"Free Delivery",
"price":"15",
"note":"Delicious"
},
{
"name":"Chick-Fil-A",
"imageURL":"https://media.istockphoto.com/photos/chicken-bacon-club-sandwich-picture-id585602032?k=6&m=585602032&s=612x612&w=0&h=DzlMVMOaqC25Zf78NPGzr9nLOf7wANEgv9u_vScu4d8=",
"rating":"5.0",
"deliveryTime":"15 min",
"deliveryCharges":"3",
"price":"7",
"note":"Classic"
},
{
"name":"Mac & Cheese",
"imageURL":"https://media.istockphoto.com/photos/homemade-baked-creamy-macaroni-and-cheese-picture-id483485720?k=6&m=483485720&s=612x612&w=0&h=u2Wb4hR0cIqNAm8q_4j-oFPrtC4hT_YXaq2srA2zmqI=",
"rating":"4.7",
"deliveryTime":"20 min",
"deliveryCharges":"1",
"price":"4",
"note":"Homestyle"
}
],
"recommended":[
{
"name":"Chicken Tikka Masala",
"imageURL":"https://media.istockphoto.com/photos/chicken-tikka-masala-curry-with-rice-and-naan-bread-picture-id1143530019?k=6&m=1143530019&s=612x612&w=0&h=aOCxTVcwi88NHCX9-xgNu7cmPX9rq5AGtEVYblNTnGc=",
"rating":"4.8",
"deliveryTime":"25 min",
"deliveryCharges":"2",
"price":"14",
"note":"Fan Favorite"
},
{
"name":"Strawberry Milkshake",
"imageURL":"https://thumbs.dreamstime.com/b/strawberry-milkshake-covered-whipped-cream-plastic-glass-isolated-white-background-44432579.jpg",
"rating":"4.5",
"deliveryTime":"10 min",
"deliveryCharges":"0",
"price":"4",
"note":"Chilly"
},
{
"name":"3 Tacos",
"imageURL":"https://previews.123rf.com/images/gdolgikh/gdolgikh1703/gdolgikh170300221/74432760-mexican-tacos-with-beef.jpg",
"rating":"4.6",
"deliveryTime":"17 min",
"deliveryCharges":"1",
"price":"12",
"note":"Hard or Soft Shell"
}
],
"allmenu":[
{
"name":"Pizza",
"imageURL":"https://static4.depositphotos.com/1016418/315/i/600/depositphotos_3158962-stock-photo-pepperoni-pizza-isolated.jpg",
"rating":"4.8",
"deliveryTime":"45 min",
"deliveryCharges":"Free Delivery",
"price":"15",
"note":"Delicious"
},
{
"name":"Chick-Fil-A",
"imageURL":"https://media.istockphoto.com/photos/chicken-bacon-club-sandwich-picture-id585602032?k=6&m=585602032&s=612x612&w=0&h=DzlMVMOaqC25Zf78NPGzr9nLOf7wANEgv9u_vScu4d8=",
"rating":"5.0",
"deliveryTime":"15 min",
"deliveryCharges":"3",
"price":"7",
"note":"Classic"
},
{
"name":"Mac & Cheese",
"imageURL":"https://media.istockphoto.com/photos/homemade-baked-creamy-macaroni-and-cheese-picture-id483485720?k=6&m=483485720&s=612x612&w=0&h=u2Wb4hR0cIqNAm8q_4j-oFPrtC4hT_YXaq2srA2zmqI=",
"rating":"4.7",
"deliveryTime":"20 min",
"deliveryCharges":"1",
"price":"4",
"note":"Homestyle"
},
{
"name":"Chicken Tikka Masala",
"imageURL":"https://media.istockphoto.com/photos/chicken-tikka-masala-curry-with-rice-and-naan-bread-picture-id1143530019?k=6&m=1143530019&s=612x612&w=0&h=aOCxTVcwi88NHCX9-xgNu7cmPX9rq5AGtEVYblNTnGc=",
"rating":"4.8",
"deliveryTime":"25 min",
"deliveryCharges":"2",
"price":"14",
"note":"Fan Favorite"
},
{
"name":"Strawberry Milkshake",
"imageURL":"https://thumbs.dreamstime.com/b/strawberry-milkshake-covered-whipped-cream-plastic-glass-isolated-white-background-44432579.jpg",
"rating":"4.5",
"deliveryTime":"10 min",
"deliveryCharges":"0",
"price":"4",
"note":"Chilly"
},
{
"name":"3 Tacos",
"imageURL":"https://previews.123rf.com/images/gdolgikh/gdolgikh1703/gdolgikh170300221/74432760-mexican-tacos-with-beef.jpg",
"rating":"4.6",
"deliveryTime":"17 min",
"deliveryCharges":"1",
"price":"12",
"note":"Hard or Soft Shell"
}
]
}
I have models for Allmenu, FoodData, Popular, and Recommended.
AllMenu:
package com.example.bearcateats.model;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
#Generated("jsonschema2pojo")
public class Allmenu {
#SerializedName("name")
#Expose
private String name;
#SerializedName("imageURL")
#Expose
private String imageURL;
#SerializedName("rating")
#Expose
private String rating;
#SerializedName("deliveryTime")
#Expose
private String deliveryTime;
#SerializedName("deliveryCharges")
#Expose
private String deliveryCharges;
#SerializedName("price")
#Expose
private String price;
#SerializedName("note")
#Expose
private String note;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
public String getRating() {
return rating;
}
public void setRating(String rating) {
this.rating = rating;
}
public String getDeliveryTime() {
return deliveryTime;
}
public void setDeliveryTime(String deliveryTime) {
this.deliveryTime = deliveryTime;
}
public String getDeliveryCharges() {
return deliveryCharges;
}
public void setDeliveryCharges(String deliveryCharges) {
this.deliveryCharges = deliveryCharges;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
}
FoodData:
package com.example.bearcateats.model;
import java.util.List;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
#Generated("jsonschema2pojo")
public class FoodData {
#SerializedName("popular")
#Expose
private List<Popular> popular = null;
#SerializedName("recommended")
#Expose
private List<Recommended> recommended = null;
#SerializedName("allmenu")
#Expose
private List<Allmenu> allmenu = null;
public List<Popular> getPopular() {
return popular;
}
public void setPopular(List<Popular> popular) {
this.popular = popular;
}
public List<Recommended> getRecommended() {
return recommended;
}
public void setRecommended(List<Recommended> recommended) {
this.recommended = recommended;
}
public List<Allmenu> getAllmenu() {
return allmenu;
}
public void setAllmenu(List<Allmenu> allmenu) {
this.allmenu = allmenu;
}
}
Popular:
package com.example.bearcateats.model;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
#Generated("jsonschema2pojo")
public class Popular {
#SerializedName("name")
#Expose
private String name;
#SerializedName("imageURL")
#Expose
private String imageURL;
#SerializedName("rating")
#Expose
private String rating;
#SerializedName("deliveryTime")
#Expose
private String deliveryTime;
#SerializedName("deliveryCharges")
#Expose
private String deliveryCharges;
#SerializedName("price")
#Expose
private String price;
#SerializedName("note")
#Expose
private String note;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
public String getRating() {
return rating;
}
public void setRating(String rating) {
this.rating = rating;
}
public String getDeliveryTime() {
return deliveryTime;
}
public void setDeliveryTime(String deliveryTime) {
this.deliveryTime = deliveryTime;
}
public String getDeliveryCharges() {
return deliveryCharges;
}
public void setDeliveryCharges(String deliveryCharges) {
this.deliveryCharges = deliveryCharges;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
}
Recommended:
package com.example.bearcateats.model;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
#Generated("jsonschema2pojo")
public class Recommended {
#SerializedName("name")
#Expose
private String name;
#SerializedName("imageURL")
#Expose
private String imageURL;
#SerializedName("rating")
#Expose
private String rating;
#SerializedName("deliveryTime")
#Expose
private String deliveryTime;
#SerializedName("deliveryCharges")
#Expose
private String deliveryCharges;
#SerializedName("price")
#Expose
private String price;
#SerializedName("note")
#Expose
private String note;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
public String getRating() {
return rating;
}
public void setRating(String rating) {
this.rating = rating;
}
public String getDeliveryTime() {
return deliveryTime;
}
public void setDeliveryTime(String deliveryTime) {
this.deliveryTime = deliveryTime;
}
public String getDeliveryCharges() {
return deliveryCharges;
}
public void setDeliveryCharges(String deliveryCharges) {
this.deliveryCharges = deliveryCharges;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
}
Main:
package com.example.bearcateats;
import android.os.Bundle;
import android.widget.Toast;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.bearcateats.adapters.PopularAdapter;
import com.example.bearcateats.adapters.RecommendedAdapter;
import com.example.bearcateats.model.Allmenu;
import com.example.bearcateats.model.FoodData;
import com.example.bearcateats.model.Popular;
import com.example.bearcateats.model.Recommended;
import com.example.bearcateats.retrofit.ApiInterface;
import com.example.bearcateats.retrofit.RetrofitClient;
import com.example.bearcateats.adapters.AllMenuAdapter;
import java.util.List;
public class MainActivity extends AppCompatActivity {
ApiInterface apiInterface;
RecyclerView popularRecyclerView, recommendedRecyclerView, allMenuRecyclerView;
PopularAdapter popularAdapter;
RecommendedAdapter recommendedAdapter;
AllMenuAdapter allMenuAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
apiInterface = RetrofitClient.getRetrofitInstance().create(ApiInterface.class);
Call<List<FoodData>> call = apiInterface.getAllData();
call.enqueue(new Callback<List<FoodData>>() {
#Override
public void onResponse(Call<List<FoodData>> call, Response<List<FoodData>> response) {
System.out.println("TEST!!!!!!!!!!!!!!");
List<FoodData> MenuList;
MenuList = response.body();
if(MenuList == null) {
System.out.println("MenuList!!!!!!!!!!!!!!");
}
List <FoodData> test1 = (List<FoodData>) MenuList.get(0);
List<Popular> popular = ((FoodData) test1).getPopular();
getPopularData(popular);
System.out.println("GET POPULAR RAN!!!!!!!!!!!!!!");
getRecommendedData(MenuList.get(0).getRecommended());
}
#Override
public void onFailure(Call<List<FoodData>> call, Throwable t) {
Toast.makeText(MainActivity.this, "Server is not responding.", Toast.LENGTH_SHORT).show();
}
});
}
private void getPopularData(List<Popular> popularList){
popularRecyclerView = findViewById(R.id.popular_recycler);
popularAdapter = new PopularAdapter(this, popularList);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
popularRecyclerView.setLayoutManager(layoutManager);
popularRecyclerView.setAdapter(popularAdapter);
}
private void getRecommendedData(List<Recommended> recommendedList){
recommendedRecyclerView = findViewById(R.id.recommended_recycler);
recommendedAdapter = new RecommendedAdapter(this, recommendedList);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
recommendedRecyclerView.setLayoutManager(layoutManager);
recommendedRecyclerView.setAdapter(recommendedAdapter);
}
private void getAllMenu(List<Allmenu> allmenuList){
allMenuRecyclerView = findViewById(R.id.all_menu_recycler);
allMenuAdapter = new AllMenuAdapter(this, allmenuList);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
allMenuRecyclerView.setLayoutManager(layoutManager);
allMenuRecyclerView.setAdapter(allMenuAdapter);
allMenuAdapter.notifyDataSetChanged();
}
}
FoodDetails
{
// now we will get data from intent and set to UI
ImageView imageView;
TextView itemName, itemPrice, itemRating;
RatingBar ratingBar;
String name, price, rating, imageUrl;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_food_details);
Intent intent = getIntent();
name = intent.getStringExtra("name");
price = intent.getStringExtra("price");
rating = intent.getStringExtra("rating");
imageUrl = intent.getStringExtra("image");
imageView = findViewById(R.id.imageView5);
itemName = findViewById(R.id.name);
itemPrice = findViewById(R.id.price);
itemRating = findViewById(R.id.rating);
ratingBar = findViewById(R.id.ratingBar);
Glide.with(getApplicationContext()).load(imageUrl).into(imageView);
itemName.setText(name);
itemPrice.setText("$ "+price);
itemRating.setText(rating);
ratingBar.setRating(Float.parseFloat(rating));
}
}
Couple of silly mistakes are there. I have fixed all your bugs. Nothing wrong with your JSON or Response data classes. Correct response is received inside onResponse() callback. Issues are present other parts of your code. Just follow step by step.
Step-1
Replace below code while parsing response data from api call like:
call.enqueue(new Callback<List<FoodData>>() {
#Override
public void onResponse(Call<List<FoodData>> call, Response<List<FoodData>> response) {
if (response.isSuccessful()){
if (response.body() != null){
List<Popular> popular = response.body().get(0).getPopular();
getPopularData(popular);
getRecommendedData(response.body().get(0).getRecommended());
}
}
}
#Override
public void onFailure(Call<List<FoodData>> call, Throwable t) {
Toast.makeText(MainActivity.this, "Server is not responding.", Toast.LENGTH_SHORT).show();
}
});
Step-2
Inside PopularAdapter class replace getItemCount() method as below:
#Override
public int getItemCount() {
//return 0; // Returning 0 will show nothing in RecyclerView.
return popularList.size();
}
Step-3:
Inside RecommendedAdapter class you have used wrong xml for ViewHolder. Replace like below:
#NonNull
#Override
public RecommendedViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//View view = LayoutInflater.from(context).inflate(R.layout.popular_recycler_items, parent, false);
View view = LayoutInflater.from(context).inflate(R.layout.recommended_recyvler_items, parent, false);
return new RecommendedViewHolder(view);
}
And also replace getItemCount() method like below:
#Override
public int getItemCount() {
return recommendedList.size();
}
UPDATE:-
Why are you calling same api inside onSuccess() of api call ? I have update your onCreate() method like below:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
apiInterface = RetrofitClient.getRetrofitInstance().create(ApiInterface.class);
Call<List<FoodData>> call = apiInterface.getAllData();
call.enqueue(new Callback<List<FoodData>>() {
#Override
public void onResponse(Call<List<FoodData>> call, Response<List<FoodData>> response) {
if (response.isSuccessful()) {
if (response.body() != null) {
getPopularData(response.body().get(0).getPopular());
getRecommendedData(response.body().get(0).getRecommended());
getAllMenu(response.body().get(0).getAllmenu());
}
}
/*
call.clone().enqueue(new Callback<List<FoodData>>() {
#Override
public void onResponse(Call<List<FoodData>> call, Response<List<FoodData>> response) {
if (response.isSuccessful()) {
if (response.body() != null) {
response.code();
getPopularData(response.body().get(0).getPopular());
getRecommendedData(response.body().get(0).getRecommended());
getAllMenu(response.body().get(0).getAllmenu());
}
}
}
#Override
public void onFailure(Call<List<FoodData>> call, Throwable t) {
response.code();
Toast.makeText(MainActivity.this, t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
});*/
}
#Override
public void onFailure(Call<List<FoodData>> call, Throwable t) {
Toast.makeText(MainActivity.this, t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
});
}
I see your JSON in https://francescainfranca.github.io/menuJSON/index.json is an Single FoodData JSON Object and Not an JSONArray.
This is causing the following exception when we run the application. So either Change the JSON structure or Make the application use FoodData directly instead of List<FoodData>.
Also the Toast Message (Server is not responding) is being shown on run which you have added on Failure Response.
Hope this helps you. Thanks.

How to store data from REST API with Volley for Android

I try to get data from my Api, I can get data and convert it into an object class I created and show it but I can't store all objects instances in an list. Someone knows ?
I tried to add every element I got in a List then try to get elements from it after but doesn't work, the list stays empty.
This is what my API returns :
{"_id":"60683c5bcdfcb74689bc8382","questionId":3,"question":"Question 3","choices":"1-/-2-/-3-/-4","category":"Other","difficulty":"Easy"}
This is my "ApiTest activity" :
package com.jojo.jojozquizz;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import com.jojo.jojozquizz.model.Question;
import com.jojo.jojozquizz.model.QuestionBank;
import com.jojo.jojozquizz.tools.APIListener;
import org.json.JSONException;
import org.json.JSONObject;
public class ApiTests extends AppCompatActivity implements APIListener {
private TextView text;
public static final String TAG = "MyTag";
private QuestionBank mQuestionBank;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_api_tests);
mQuestionBank = new QuestionBank();
text = findViewById(R.id.api_text);
String url = "https://nextfor.studio/questions/test";
getQuestionFromApi(url);
}
private void getQuestionFromApi(String url) {
APIListener listener = this;
RequestQueue requestQueue = Volley.newRequestQueue(this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
Log.d(TAG, "onResponse: " + response.toString());
Question question = new Question();
question.setId(response.getInt("questionId"));
question.setQuestion(response.getString("question"));
question.setChoices(response.getString("choices"));
question.setCategory(response.getString("category"));
question.setDifficulty(response.getString("difficulty"));
listener.questionReceived(question);
} catch (JSONException e) {
Log.i(TAG, e.getMessage());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "onErrorResponse: " + error.getMessage());
}
});
requestQueue.add(jsonObjectRequest);
}
#Override
public void questionReceived(Question q) {
mQuestionBank.addQuestion(q);
}
}
Question class :
package com.jojo.jojozquizz.model;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.PrimaryKey;
import java.io.Serializable;
import java.util.List;
#Entity(tableName = "questions")
public class Question implements Serializable {
#PrimaryKey()
#ColumnInfo(name = "id")
private long id;
#ColumnInfo(name = "question")
private String mQuestion;
#Ignore
private List<String> mChoiceList;
#ColumnInfo(name = "choices")
private String mChoices;
#ColumnInfo(name = "answer_index")
private int mAnswerIndex;
#ColumnInfo(name = "categorie")
private String mCategory;
#Ignore
private String mTrueAnswer;
#ColumnInfo(name = "difficulty")
private String mDifficulty;
public Question() {
}
public Question(int id, String mQuestion, List<String> mChoiceList, String mCategorie, String mDifficulty) {
this.id = id;
this.mQuestion = mQuestion;
this.mChoices = mChoiceList.get(0) + "-/-" + mChoiceList.get(1) + "-/-" + mChoiceList.get(2) + "-/-" + mChoiceList.get(3);
this.mAnswerIndex = 0;
this.mCategory = mCategorie;
this.mDifficulty = mDifficulty;
}
public Question(String mQuestion, List<String> mChoiceList, String mCategorie, String mDifficulty) {
this.mQuestion = mQuestion;
this.mChoices = mChoiceList.get(0) + "-/-" + mChoiceList.get(1) + "-/-" + mChoiceList.get(2) + "-/-" + mChoiceList.get(3);
this.mAnswerIndex = 0;
this.mCategory = mCategorie;
this.mDifficulty = mDifficulty;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getQuestion() {
return mQuestion;
}
public void setQuestion(String question) {
mQuestion = question;
}
public List<String> getChoiceList() {
return mChoiceList;
}
public void setChoiceList(List<String> choiceList) {
mChoiceList = choiceList;
}
public String getChoices() {
return mChoices;
}
public void setChoices(String choices) {
mChoices = choices;
}
public void setAnswerIndex(int mAnswerIndex) {
this.mAnswerIndex = mAnswerIndex;
}
public int getAnswerIndex() {
return mAnswerIndex;
}
public String getCategory() {
return mCategory;
}
public void setCategory(String categorie) {
mCategory = categorie;
}
public String getTrueAnswer() {
return mTrueAnswer;
}
public void setTrueAnswer(String trueAnswer) {
mTrueAnswer = trueAnswer;
}
public String getDifficulty() {
return mDifficulty;
}
public void setDifficulty(String difficulty) {
mDifficulty = difficulty;
}
}
QuestionBank (this is like a list of Questions) :
package com.jojo.jojozquizz.model;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public class QuestionBank {
private List<Question> mQuestionList;
public int mNextQuestionIndex;
public QuestionBank() {
mQuestionList = new LinkedList<>();
mNextQuestionIndex = 0;
}
public QuestionBank(List<Question> questionList, boolean shuffle) {
mQuestionList = questionList;
if (shuffle)
Collections.shuffle(mQuestionList);
mNextQuestionIndex = 0;
}
public Question getQuestion() {
if (mNextQuestionIndex == mQuestionList.size())
mNextQuestionIndex = 0;
return mQuestionList.get(mNextQuestionIndex++);
}
public Question getQuestion(int i) {
return mQuestionList.get(i);
}
public void reShuffle() {
Collections.shuffle(mQuestionList);
}
public void addQuestion(Question question) {
mQuestionList.add(question);
}
public int returnListSize() {
return mQuestionList.size();
}
}
And APIListener :
package com.jojo.jojozquizz.tools;
import com.jojo.jojozquizz.model.Question;
public interface APIListener {
void questionReceived(Question q);
}
API calling is an asynchronous process. So getQuestionFromApi(url); might took some time, so if you try text.setText(mQuestionBank.getQuestion(0).getQuestion()); after getQuestionFromApi(url); line, it won't work. You could use LiveData to handle this case. Like:
class QuestionBank {
MutableLiveData<List<Question>> mQuestionList;
public int mNextQuestionIndex;
public QuestionBank() {
mQuestionList = new MutableLiveData<>(new LinkedList<>());
mNextQuestionIndex = 0;
}
public QuestionBank(List<Question> questionList, boolean shuffle) {
mQuestionList.setValue(questionList);
if (shuffle)
Collections.shuffle(mQuestionList.getValue());
mNextQuestionIndex = 0;
}
public Question getQuestion() {
if (mNextQuestionIndex == mQuestionList.getValue().size())
mNextQuestionIndex = 0;
return mQuestionList.getValue().get(mNextQuestionIndex++);
}
public Question getQuestion(int i) {
return mQuestionList.getValue().get(i);
}
public void reShuffle() {
Collections.shuffle(mQuestionList.getValue());
}
public void addQuestion(Question question) {
List<Question> tempQ = mQuestionList.getValue();
tempQ.add(question);
mQuestionList.setValue(tempQ);
}
public int returnListSize() {
return mQuestionList.getValue().size();
}
}
And inside onCreate() observe if any data has been added or not and then setText() to TextView. Like:
QuestionBank questionBank = new QuestionBank();
questionBank.mQuestionList.observe(getViewLifecycleOwner(), new Observer<List<Question>>() {
#Override
public void onChanged(List<Question> questions) {
if (!questions.isEmpty()){
textView.setText(questions.get(0).getQuestion());
Log.d("TAG==>>","New Question added Total size = "+questions.size());
}
}
});

Sorting data in List by specific value

I have an issue where my recyclerview adds new items at the end, whereas I want the latest items at the top upon user refresh. I've been scratching around all over the net and it essentially boils down to adding setreverseLayout or setStackFromEnd. This gives other complications such as the recycler view not scrolling to the top to the latest item.
I then had a thought of maybe ordering my data list by a specific value and then it should return it as I want it. Can this be done and would it resolve my issue? I want to sort it by value adopt_rownum desc.
My Custom Adapter
package com.example.admin.paws;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import java.util.List;
/**
* Created by admin on 9/16/2016.
*/
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
public Context context;
public List<MyData> my_data;
public CustomAdapter(Context context, List<MyData> my_data) {
this.context = context;
this.my_data = my_data;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardnew,parent,false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
String name = my_data.get(position).getName();
String age = my_data.get(position).getAge();
String gender = my_data.get(position).getGender();
String SubstAge = age.substring(0,age.indexOf("(") -1);
String NameAgeGender = name + ", " + SubstAge + ", " + gender;
holder.about.setText(my_data.get(position).getAbout());
holder.NameAgeGender.setText(NameAgeGender);
Glide.with(context).load(my_data.get(position).getPhoto_path()).into(holder.photo_path);
//activity_card_details vars
// final String about = my_data.get(position).getAbout();
final String adoptId = my_data.get(position).getId()+"";
final String photo_path_dtls = my_data.get(position).getPhoto_path();
final String listedDate = my_data.get(position).getDatetime_listed();
final String status = my_data.get(position).getStatus();
final String breed = my_data.get(position).getBreed();
final String source = my_data.get(position).getSource();
final String contact_info = my_data.get(position).getContact_info();
final String suburb = my_data.get(position).getSuburb();
final String city = my_data.get(position).getCity();
final String province = my_data.get(position).getProvince();
final String concat_location = suburb + ", " + city + ", " + province;
final String viewCounter = my_data.get(position).getViewCounter()+"";
//When click on photo
holder.photo_path.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context,CardDetailsActivity.class);
intent.putExtra("listedDate",listedDate);
intent.putExtra("adoptId",adoptId);
// intent.putExtra("about",about);
intent.putExtra("status",status);
intent.putExtra("breed",breed);
intent.putExtra("source",source);
intent.putExtra("contactinfo",contact_info);
intent.putExtra("location",concat_location);
intent.putExtra("photo_path_dtls",photo_path_dtls);
intent.putExtra("viewCounter",viewCounter);
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return my_data.size();
}
public class ViewHolder extends RecyclerView.ViewHolder
{
public TextView NameAgeGender;
public ImageView photo_path;
public TextView about;
private ViewHolder(View itemView) {
super(itemView);
about = (TextView) itemView.findViewById(R.id.about);
NameAgeGender = (TextView) itemView.findViewById(R.id.tvNameAgeGender);
// NameAgeGender.setTextColor(Color.parseColor("#9C9393"));
Typeface typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Lato-Medium.ttf");
NameAgeGender.setTypeface(typeface);
//NameAgeGender.setBackgroundColor(Color.parseColor("#F35959"));
photo_path = (ImageView) itemView.findViewById(R.id.photo_path);
}
}
}
My DataList
package com.example.admin.paws;
public class MyData {
//the must be in the same order of the select column order
public int adopt_rownum
,viewCounter
,adopt_id;
private String
name
,type
,breed
,age
,gender
,size
,about
,photo_path
,source
,contact_info
,suburb
,city
,province
,datetime_listed
,status;
public MyData(
int adopt_rownum,
int viewCounter,
int adopt_id,
String name,
String type,
String breed,
String age,
String gender,
String size,
String about,
String photo_path,
String source,
String contact_info,
String suburb,
String city,
String province,
String datetime_listed,
String status)
{
this.adopt_rownum = adopt_rownum;
this.viewCounter = viewCounter;
this.adopt_id = adopt_id;
this.name = name;
this.type = type;
this.breed = breed;
this.age = age;
this.gender = gender;
this.size = size;
this.about = about;
this.photo_path = photo_path;
this.source = source;
this.contact_info = contact_info;
this.suburb = suburb;
this.city = city;
this.province = province;
this.datetime_listed = datetime_listed;
this.status = status;
}
//adopt_rownum used for filtering the records.
public int getAdopt_rownum() {
return adopt_rownum;
}
//viewcounter
public int getViewCounter() {
return viewCounter;
}
//adopt_id
public int getId() {
return adopt_id;
}
public void setId(int adopt_id) {
this.adopt_id = adopt_id;
}
//name
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//type
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
//breed
public String getBreed() {
return breed;
}
public void setBreed(String breed) {
this.breed = breed;
}
//age
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
//gender
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.age = gender;
}
//size
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
//about
public String getAbout() {
return about;
}
public void setAbout(String about) {
this.about = about;
}
//photo path
public String getPhoto_path() {
return photo_path;
}
public void setPhoto_path(String photo_path) {
this.photo_path = photo_path;
}
//source
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
//contact_info
public String getContact_info() {
return contact_info;
}
public void setContact_info(String contact_info) {
this.contact_info = contact_info;
}
//suburb
public String getSuburb() {
return suburb;
}
public void setSuburb(String suburb) {
this.contact_info = suburb;
}
//city
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
//province
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
//datetime_listed
public String getDatetime_listed() {
return datetime_listed;
}
public void setDatetime_listed(String datetime_listed) {
this.datetime_listed = datetime_listed;
}
//status
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
The fragment that displays the results. Another question on the side, inside this fragment for load_data_from_server its giving me a warning that "This Async task should be static or leaks might occur". I have no idea what this means since I'm completely new to JAVA.
package com.example.admin.paws;
import android.app.Activity;
import android.content.Context;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
/**
* A simple {#link Fragment} subclass.
* Activities that contain this fragment must implement the
* {#link feedFragment.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {#link feedFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class feedFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
public Activity FragActivity;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private List<MyData> data_list;
private CustomAdapter adapter;
RecyclerView recyclerView;
public String EndOfFeed;
private OnFragmentInteractionListener mListener;
public feedFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment fragment_feed.
*/
// TODO: Rename and change types and number of parameters
public static feedFragment newInstance(String param1, String param2) {
feedFragment fragment = new feedFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true);
View rootView = inflater.inflate(R.layout.fragment_feed, container, false);
final GridLayoutManager gridLayoutManager;
final SwipeRefreshLayout swipeRefreshLayout = rootView.findViewById(R.id.feedRefresh);
TextView tvEndOfFeed = rootView.findViewById(R.id.tvEndOfFeed);
tvEndOfFeed.setText(EndOfFeed);
//recycler view
recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
data_list = new ArrayList<>();
load_data_from_server(0, "getFeed.php");
gridLayoutManager = new GridLayoutManager(getActivity(), 1); //2 nr of cards next to each other
recyclerView.setLayoutManager(gridLayoutManager);
//gridLayoutManager.setReverseLayout(true);
adapter = new CustomAdapter(getActivity(), data_list);
recyclerView.setAdapter(adapter);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (gridLayoutManager.findLastCompletelyVisibleItemPosition() == data_list.size() - 1) {
load_data_from_server(data_list.get(data_list.size() - 1).getAdopt_rownum(), "getFeed.php");
}
}
});
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
//this works but issue with the ordering of the adoptrownum
load_data_from_server(data_list.get(data_list.size() -1).getAdopt_rownum(), "refreshFeed.php");
swipeRefreshLayout.setRefreshing(false);
}
});
return rootView;
}
private void load_data_from_server(final int adopt_id, final String phpScript) {
AsyncTask<Integer,Void,Void> task = new AsyncTask<Integer, Void, Void>() {
#Override
protected Void doInBackground(Integer... integers) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://10.0.2.2/app_scripts/"+phpScript+"?adopt_rownum="+integers[0])
.build();
try {
Response response = client.newCall(request).execute();
JSONArray array = new JSONArray(response.body().string());
for (int i=0; i<array.length(); i++){
JSONObject object = array.getJSONObject(i);
MyData data = new MyData(
object.getInt("ADOPT_ROWNUM"),
object.getInt("VIEWCOUNTER"),
object.getInt("ADOPT_ID"),
object.getString("NAME"),
object.getString("TYPE"),
object.getString("BREED"),
object.getString("AGE"),
object.getString("GENDER"),
object.getString("SIZE"),
object.getString("ABOUT"),
object.getString("PHOTO_PATH"),
object.getString("SOURCE"),
object.getString("CONTACT_INFO"),
object.getString("SUBURB"),
object.getString("CITY"),
object.getString("PROVINCE"),
object.getString("DATETIME_LISTED"),
object.getString("STATUS")
);
data_list.add(data);
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
System.out.println("End of content"+e);
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
adapter.notifyDataSetChanged();
}
};
task.execute(adopt_id);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
I added the Comparator as instructed below but the output is a bit weird...
public class MyComparator implements Comparator<MyData > {
#Override
public int compare(final MyData o1, final MyData o2) {
Log.d("APP", "compare Starting... ");
Integer val1 = o1.getAdopt_rownum();
Log.d("APP", "compare val1... "+val1);
Integer val2 = o2.getAdopt_rownum();
Log.d("APP", "compare val1... "+val2);
Log.d("APP", "compare val1 and val2 ="+val1.compareTo(val2));
return val1.compareTo(val2);
}
}
output
compare Starting...
compare val1... 2
compare val2... 1
compare val1 and val2 =1
...
compare Starting...
compare val1... 14
compare val2... 15
compare val2 and val2 =1
Below is how i implemented it in my fragment
private void load_data_from_server(final int adopt_id, final String phpScript) {
AsyncTask<Integer,Void,Void> task = new AsyncTask<Integer, Void, Void>() {
#Override
protected Void doInBackground(Integer... integers) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://10.0.2.2/app_scripts/"+phpScript+"?adopt_rownum="+integers[0])
.build();
try {
Response response = client.newCall(request).execute();
JSONArray array = new JSONArray(response.body().string());
for (int i=0; i<array.length(); i++){
JSONObject object = array.getJSONObject(i);
MyData data = new MyData(
object.getInt("ADOPT_ROWNUM"),
object.getInt("VIEWCOUNTER"),
object.getInt("ADOPT_ID"),
object.getString("NAME"),
object.getString("TYPE"),
object.getString("BREED"),
object.getString("AGE"),
object.getString("GENDER"),
object.getString("SIZE"),
object.getString("ABOUT"),
object.getString("PHOTO_PATH"),
object.getString("SOURCE"),
object.getString("CONTACT_INFO"),
object.getString("SUBURB"),
object.getString("CITY"),
object.getString("PROVINCE"),
object.getString("DATETIME_LISTED"),
object.getString("STATUS")
);
data_list.add(data);
**Collections.sort(data_list,new MyComparator());**
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
//System.out.println("End of content"+e);
EndOfFeed = e+"";
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
adapter.notifyDataSetChanged();
}
};
task.execute(adopt_id);
}
You can sort list by a property using the following code:
Collections.sort(myList, new MyComparator());
public static class MyComparator implements Comparator<MyData > {
#Override
public int compare(final MyData o1, final MyData o2) {
return o1.getAdoptRownum().compareTo(o2.getAdoptRownum());
}
}
I usually declare comparators inside the relevant POJO class. Then you can call Collections.sort whenever you refresh your data.

Categories

Resources