I have a problem in the application, I want to make a function to add a recipe to my favorites, but there is a problem, everything seems to look fine, but when I click on the save button, I first compare the current icon with two icons selected and not selected, if selected, I delete a recipe from my favorite firebase database, and if it’s not selected, I add it, but there is a problem when I press my if else system for some reason starts in a loop and even the button seems to be pressed by itself I don’t know why this happens, can you please help, and i use RecyclerView.
My Recipe Item:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:id="@ id/cardView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:foregroundGravity="center"
app:cardCornerRadius="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical"
android:paddingBottom="30dp">
<ImageView
android:id="@ id/recipeImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:contentDescription="@string/app_name"
android:maxHeight="260dp"
android:scaleType="fitXY"
android:transitionName="courseImage" />
<TextView
android:id="@ id/recipeTitle"
android:layout_width="223dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:fontFamily="@font/baloo"
android:text="1234567890123456"
android:textColor="@color/black"
android:textSize="25sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="52dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:fontFamily="@font/baloo"
android:text="By"
android:textColor="@color/black"
android:textSize="16sp" />
<TextView
android:id="@ id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:fontFamily="@font/baloo"
android:text="Username"
android:textColor="@color/textColor"
android:textSize="18sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="60dp">
<ImageView
android:id="@ id/imageView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginRight="5dp"
android:layout_weight="1"
android:contentDescription="TODO"
app:srcCompat="@drawable/ic_time_svgrepo_com" />
</LinearLayout>
<TextView
android:id="@ id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/baloo"
android:text="time"
android:textColor="@color/black" />
</LinearLayout>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@ id/saveBtn"
android:layout_width="31dp"
android:layout_height="36dp"
android:layout_marginLeft="190dp"
android:layout_weight="1"
app:srcCompat="@drawable/save" />
</androidx.appcompat.widget.LinearLayoutCompat>
</LinearLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
My Adapter:
public class RecipeAdapter extends RecyclerView.Adapter<RecipeAdapter.RecipeViewHolder> {
FirebaseAuth mAuth;
FirebaseUser mUser;
DatabaseReference mRef;
DatabaseReference mRef2;
DatabaseReference mRef3;
DatabaseReference mRef4;
Context context;
public List<Recipe> recipes;
public RecipeAdapter(Context context, List<Recipe> courses) {
this.context = context;
this.recipes = courses;
}
@NonNull
@Override
public RecipeViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View recipeItems = LayoutInflater.from(context).inflate(R.layout.recipe_item, parent, false);
return new RecipeAdapter.RecipeViewHolder(recipeItems);
}
@Override
public void onBindViewHolder(@NonNull RecipeViewHolder holder, @SuppressLint("RecyclerView") int position) {
mAuth = FirebaseAuth.getInstance();
mUser = mAuth.getCurrentUser();
mRef = FirebaseDatabase.getInstance().getReference().child("users");
mRef2 = FirebaseDatabase.getInstance().getReference().child("count");
mRef4 = FirebaseDatabase.getInstance().getReference().child("count2").child(mUser.getUid());
mRef3 = FirebaseDatabase.getInstance().getReference().child("favorite").child(mUser.getUid());
//Listener for favorite Btn
holder.saveBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mRef4.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot1) {
try {
if (holder.saveBtn.getDrawable().getConstantState().equals(context.getDrawable(R.drawable.save).getConstantState())) {
System.out.println("g");
mRef3.child(recipes.get(position).id).setValue("");
mRef4.setValue(Integer.parseInt(snapshot1.getValue().toString()) 1);
holder.saveBtn.setImageResource(R.drawable.save2);
} else {
System.out.println("b");
mRef3.child(recipes.get(position).id).removeValue();
holder.saveBtn.setImageResource(R.drawable.save);
}
return;
} catch (IndexOutOfBoundsException e) {
}
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
}
});
mRef4.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot1) {
System.out.println(snapshot1.getValue().toString());
mRef3.child(recipes.get(position).id).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
if (snapshot.getValue() == null) {
} else {
holder.saveBtn.setImageResource(R.drawable.save2);
}
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(context, RecipePage.class);
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(
(Activity) context,
new Pair<View, String>(holder.recipeImage, "recipeImage")
);
intent.putExtra("recipeImage", recipes.get(position).getPhotoLink());
intent.putExtra("recipeTitle", recipes.get(position).getTitle());
intent.putExtra("recipeCookTime", recipes.get(position).getCookTime());
intent.putExtra("recipeServes", recipes.get(position).getServes());
intent.putExtra("recipePrepTime", recipes.get(position).getPrepTime());
intent.putExtra("recipeAccess", recipes.get(position).getAccess());
intent.putExtra("recipeDesc", recipes.get(position).getDescription());
intent.putExtra("recipeIngr", recipes.get(position).getIngredients());
intent.putExtra("recipeDire", recipes.get(position).getDirections());
context.startActivity(intent, options.toBundle());
}
});
}
@Override
public int getItemCount() {
return recipes.size();
}
public static final class RecipeViewHolder extends RecyclerView.ViewHolder {
public ImageView recipeImage, saveBtn;
TextView username, time, title;
public RecipeViewHolder(@NonNull View itemView) {
super(itemView);
saveBtn = itemView.findViewById(R.id.saveBtn);
recipeImage = itemView.findViewById(R.id.recipeImage);
username = itemView.findViewById(R.id.username);
username.setPaintFlags(username.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
time = itemView.findViewById(R.id.time);
title = itemView.findViewById(R.id.recipeTitle);
}
}
}
CodePudding user response:
The problem is in this sort of code:
mRef4.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot1) {
try {
if (holder.saveBtn.getDrawable().getConstantState().equals(context.getDrawable(R.drawable.save).getConstantState())) {
System.out.println("g");
mRef3.child(recipes.get(position).id).setValue("");
mRef4.setValue(Integer.parseInt(snapshot1.getValue().toString()) 1);
holder.saveBtn.setImageResource(R.drawable.save2);
} else {
System.out.println("b");
mRef3.child(recipes.get(position).id).removeValue();
holder.saveBtn.setImageResource(R.drawable.save);
}
return;
} catch (IndexOutOfBoundsException e) {
}
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
You're adding a value listener to mRef4
, which means that your onDataChange
gets called immediately for the current value of mRef4
and then **every time mRef4
is modified tooSince you modify mRef4
inside onDataChange
, you're causing an infinite loop.
Most likely you want to use addListenerForSingleValueEvent
instead of addValueEventListener
:
//