0

I am currently struggling with sending an intent that has an Object which contains a List. Basically I can send the right data to another activity, but I am failing to get the List in the data. Sorry, I really don't know how to describe it.

The thing is, I am able to get the ingredients in the RecipeActivity by calling e.g. recipes.get(0).getIngredients() but in the RecipeDetailsActivity I get an error due to the fact that the List is empty. (And also I don't know how to get the correct index of the object in the DetailsActivity)

Thanks in advance!

Recipe.java

public class Recipe implements Parcelable {

    @SerializedName("id")
    @Expose
    private Integer mId;
    @SerializedName("name")
    @Expose
    private String mName;
    @SerializedName("ingredients")
    @Expose
    private List < Ingredient > mIngredients = null;
    @SerializedName("steps")
    @Expose
    private List < Step > mSteps = null;
    @SerializedName("servings")
    @Expose
    private Integer mServings;
    @SerializedName("image")
    @Expose
    private String mImage;

    protected Recipe(Parcel in ) {
        if ( in .readByte() == 0) {
            mId = null;
        } else {
            mId = in .readInt();
        }
        mName = in .readString();
        if ( in .readByte() == 0) {
            mServings = null;
        } else {
            mServings = in .readInt();
        }
        mImage = in .readString();
    }

    public static final Creator < Recipe > CREATOR = new Creator < Recipe > () {
        @Override
        public Recipe createFromParcel(Parcel in ) {
            return new Recipe( in );
        }

        @Override
        public Recipe[] newArray(int size) {
            return new Recipe[size];
        }
    };

    public Integer getId() {
        return mId;
    }

    public void setId(Integer id) {
        mId = id;
    }

    public String getName() {
        return mName;
    }

    public void setName(String name) {
        mName = name;
    }

    public List < Ingredient > getIngredients() {
        return mIngredients;
    }

    public void setIngredients(List < Ingredient > ingredients) {
        mIngredients = ingredients;
    }

    public List < Step > getSteps() {
        return mSteps;
    }

    public void setSteps(List < Step > steps) {
        mSteps = steps;
    }

    public Integer getServings() {
        return mServings;
    }

    public void setServings(Integer servings) {
        mServings = servings;
    }

    public String getImage() {
        return mImage;
    }

    public void setImage(String image) {
        mImage = image;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        if (mId == null) {
            dest.writeByte((byte) 0);
        } else {
            dest.writeByte((byte) 1);
            dest.writeInt(mId);
        }
        dest.writeString(mName);
        if (mServings == null) {
            dest.writeByte((byte) 0);
        } else {
            dest.writeByte((byte) 1);
            dest.writeInt(mServings);
        }
        dest.writeString(mImage);
    }
}

Ingredient.java

public class Ingredient {

    @SerializedName("quantity")
    @Expose
    private Double mQuantity;
    @SerializedName("measure")
    @Expose
    private String mMeasure;
    @SerializedName("ingredient")
    @Expose
    private String mIngredient;

    public Double getQuantity() {
        return mQuantity;
    }

    public void setQuantity(Double quantity) {
        mQuantity = quantity;
    }

    public String getMeasure() {
        return mMeasure;
    }

    public void setMeasure(String measure) {
        mMeasure = measure;
    }

    public String getIngredient() {
        return mIngredient;
    }

    public void setIngredient(String ingredient) {
        mIngredient = ingredient;
    }
}

RecipeActivity

public class RecipeActivity extends AppCompatActivity implements RecipeAdapter.RecipeAdapterOnClickHandler {
    private static final String TAG = RecipeActivity.class.getSimpleName();

    @BindView(R.id.recipe_recycler_view)
    RecyclerView mRecyclerView;

    private RecipeAdapter mRecipeAdapter;
    private List < Recipe > recipes;

    public static final String MY_RECIPE = "myRecipe";

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

        RecipeService service = RecipeClient.getRetrofit().create(RecipeService.class);

        Call < List < Recipe >> call = service.getAllRecipes();
        call.enqueue(new Callback < List < Recipe >> () {
            @Override
            public void onResponse(Call < List < Recipe >> call, Response < List < Recipe >> response) {
                if (response.isSuccessful()) {
                    recipes = response.body();
                    generateDataList(recipes);
                }
            }

            @Override
            public void onFailure(Call < List < Recipe >> call, Throwable t) {
                Toast.makeText(RecipeActivity.this, "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
                Log.v(TAG, t.toString());
            }
        });
    }

    private void generateDataList(List < Recipe > recipeList) {
        ButterKnife.bind(this);
        mRecipeAdapter = new RecipeAdapter(this, recipeList, RecipeActivity.this);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(RecipeActivity.this);
        mRecyclerView.setLayoutManager(layoutManager);
        mRecyclerView.setAdapter(mRecipeAdapter);
    }


    @Override
    public void onClick(int adapterPosition) {
        Context context = this;
        Class detailClass = RecipeDetailsActivity.class;

        Intent detailsIntent = new Intent(context, detailClass);
        detailsIntent.putExtra(MY_RECIPE, recipes.get(adapterPosition));
        startActivity(detailsIntent);
    }
}

RecipeDetailsActivity

public class RecipeDetailsActivity extends AppCompatActivity implements IngredientAdapter.IngredientAdapterOnClickHandler {
    private static final String TAG = RecipeDetailsActivity.class.getSimpleName();

    private Recipe recipes;
    private List < Recipe > recipeList;

    private String recipeName;
    private String ingredient;
    private Double quantity;
    private String measure;
    private List < Ingredient > ingredientList = new ArrayList < > ();
    IngredientAdapter mAdapter;

    @Nullable
    @BindView(R.id.ingredients)
    TextView ingredientsTV;
    @Nullable
    @BindView(R.id.quantity)
    TextView quantityTV;
    @BindView(R.id.recipe_details_rv)
    RecyclerView mRecyclerView;

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

        Intent intentToCatch = getIntent();
        recipes = intentToCatch.getParcelableExtra(RecipeActivity.MY_RECIPE);

        recipeName = recipes.getName();
        ingredientList = recipes.getIngredients();
        if (ingredientList != null) {
            ingredient = ingredientList.get(0).getIngredient();
            quantity = ingredientList.get(0).getQuantity();
            measure = ingredientList.get(0).getMeasure();
        } else {
            Log.v(TAG, "FAILING LOADING INGREDIENTSLIST");
        }
        setTitle(recipeName);

        ButterKnife.bind(this);

        mAdapter = new IngredientAdapter(this, ingredientList, RecipeDetailsActivity.this);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(RecipeDetailsActivity.this);
        mRecyclerView.setLayoutManager(layoutManager);
        mRecyclerView.setAdapter(mAdapter);

    }

    @Override
    public void onClick(int adapterPosition) {

    }
}

RecipeAdapter

public class RecipeAdapter extends RecyclerView.Adapter < RecipeAdapter.RecipeAdapterViewHolder > {

    private List < Recipe > mRecipeList;
    private Context mContext;
    private RecipeAdapterOnClickHandler mOnClickHandler;

    public RecipeAdapter(Context context, List < Recipe > recipeList, RecipeAdapterOnClickHandler onClickHandler) {
        mContext = context;
        mRecipeList = recipeList;
        mOnClickHandler = onClickHandler;
    }

    public interface RecipeAdapterOnClickHandler {
        void onClick(int adapterPosition);
    }

    public class RecipeAdapterViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        @BindView(R.id.recipe_name)
        TextView mRecipeName;

        public RecipeAdapterViewHolder(@NonNull View itemView) {
            super(itemView);
            itemView.setOnClickListener(this);
            ButterKnife.bind(this, itemView);
        }

        @Override
        public void onClick(View v) {
            int adapterPosition = getAdapterPosition();
            mOnClickHandler.onClick(adapterPosition);
        }

    }

    @NonNull
    @Override
    public RecipeAdapterViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        View view = layoutInflater.inflate(R.layout.recipe_list_item, parent, false);
        return new RecipeAdapterViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull RecipeAdapterViewHolder holder, int position) {
        holder.mRecipeName.setText(mRecipeList.get(position).getName());
    }

    @Override
    public int getItemCount() {
        if (mRecipeList == null) {
            return 0;
        }
        return mRecipeList.size();
    }
}

IngredientAdapter

public class IngredientAdapter extends RecyclerView.Adapter < IngredientAdapter.IngredientAdapterViewHolder > {

    private List < Ingredient > mIngredient;
    private Context mContext;
    private IngredientAdapterOnClickHandler mOnClickHandler;

    public IngredientAdapter(Context context, List < Ingredient > ingredientList, IngredientAdapterOnClickHandler onClickHandler) {
        mContext = context;
        mIngredient = ingredientList;
        mOnClickHandler = onClickHandler;
    }

    public interface IngredientAdapterOnClickHandler {
        void onClick(int adapterPosition);
    }

    public class IngredientAdapterViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        @BindView(R.id.ingredients)
        TextView ingredientTextView;
        @BindView(R.id.step_description)
        TextView stepsDescriptionTextView;
        @BindView(R.id.quantity)
        TextView quantityDescriptionTextView;

        public IngredientAdapterViewHolder(@NonNull View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }

        @Override
        public void onClick(View v) {
            int adapterPosition = getAdapterPosition();
            mOnClickHandler.onClick(adapterPosition);
        }
    }

    @NonNull
    @Override
    public IngredientAdapterViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        View view = layoutInflater.inflate(R.layout.recipe_details_list_item, parent, false);
        return new IngredientAdapterViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull IngredientAdapterViewHolder holder, int position) {
        holder.ingredientTextView.setText(mIngredient.get(position).getIngredient());
        holder.stepsDescriptionTextView.setText(mIngredient.get(position).getQuantity().toString());
        holder.quantityDescriptionTextView.setText(mIngredient.get(position).getMeasure());

    }

    @Override
    public int getItemCount() {
        if (mIngredient == null) {
            return 0;
        }
        return mIngredient.size();
    }
}
riceplant
  • 21
  • 9

1 Answers1

1

I would suggest you to make Recipe recipes variable inside a RecipeDetailsActivity public static variable. Like public static Recipe recipes. And when you're opening the Detailed activity just it like this: RecipeDetailsActivity.recipes = recipes.get(adapterPosition); This would be an easier solution I would do in this case.

oto
  • 383
  • 4
  • 18
  • `RecipeDetailsActivity.recipes = recipes.get(adapterPosition);`this part will go in the intent in the recipe activity? – riceplant Apr 08 '20 at 14:49
  • No. it will not go though intent. But there is many ways to pass though variables. One of them is to make static variable of your Activity class. and you can use it in your activity. – oto Apr 08 '20 at 17:20
  • ok I tried somehow but I am not quite sure what you mean. Can you elaborate a bit please? :) NVMD: Got it now :D – riceplant Apr 09 '20 at 08:48