How to handle user feedback via ratingbars embedded in RecyclerView?
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:padding="4dp"
android:background="@android:color/darker_gray"/>
</android.support.constraint.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardCornerRadius="4dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp">
<ImageView
android:id="@+id/imageView"
android:layout_width="80dp"
android:layout_height="80dp"
app:srcCompat="@mipmap/ic_launcher" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="18dp"
android:layout_marginStart="48dp"
android:text="Food Name"
app:layout_constraintStart_toEndOf="@+id/imageView"
app:layout_constraintTop_toTopOf="parent" />
<RatingBar
android:id="@+id/ratingBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginTop="5dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
</RelativeLayout>
</android.support.v7.widget.CardView>
package com.example.recyclerviewproject2;
public class FoodItem {
private int foodImage;
private String foodName;
private int foodRating;
public FoodItem(int foodImage, String foodName, int foodRating) {
this.foodImage = foodImage;
this.foodName = foodName;
this.foodRating = foodRating;
}
public int getFoodImage() {
return foodImage;
}
public void setFoodImage(int foodImage) {
this.foodImage = foodImage;
}
public String getFoodName() {
return foodName;
}
public void setFoodName(String foodName) {
this.foodName = foodName;
}
public int getFoodRating() {
return foodRating;
}
public void setFoodRating(int foodRating) {
this.foodRating = foodRating;
}
}
This is
package com.example.recyclerviewproject2;
import android.support.annotation.NonNull;
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.RatingBar;
import android.widget.TextView;
import java.util.ArrayList;
public class FoodAdapter extends RecyclerView.Adapter<FoodAdapter.FoodViewHolder> {
private ArrayList<FoodItem> arrayList;
public static class FoodViewHolder extends RecyclerView.ViewHolder {
private ImageView viewHolderImageView;
private TextView viewHolderTextView;
private RatingBar viewHolderRatigBar;
public FoodViewHolder(@NonNull View itemView) {
super(itemView);
viewHolderImageView = itemView.findViewById(R.id.imageView);
viewHolderTextView = itemView.findViewById(R.id.textView);
viewHolderRatigBar = itemView.findViewById(R.id.ratingBar);
}
}
public FoodAdapter(ArrayList<FoodItem> foodList) {
arrayList = foodList;
}
@NonNull
@Override
public FoodViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.food_item, viewGroup, false);
FoodViewHolder foodViewHolder = new FoodViewHolder(view);
return foodViewHolder;
}
@Override
public void onBindViewHolder(@NonNull FoodViewHolder foodViewHolder, int i) {
FoodItem currentItem = arrayList.get(i);
foodViewHolder.viewHolderImageView.setImageResource(currentItem.getFoodImage());
foodViewHolder.viewHolderTextView.setText(currentItem.getFoodName());
foodViewHolder.viewHolderRatigBar.setRating(currentItem.getFoodRating());
}
@Override
public int getItemCount() {
return arrayList.size();
}
}
And this is
package com.example.recyclerviewproject2;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.LayoutManager;
import java.util.ArrayList;
import static android.support.v7.widget.RecyclerView.*;
public class MainActivity extends AppCompatActivity {
private ArrayList<FoodItem> foodList;
private RecyclerView recyclerView;
private Adapter adapter;
private LayoutManager layoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
createFoodList();
buildRecyclerView();
}
private void createFoodList() {
foodList = new ArrayList<>();
foodList.add(new FoodItem(R.drawable.a, "a", 0));
foodList.add(new FoodItem(R.drawable.b, "b", 0));
foodList.add(new FoodItem(R.drawable.c, "c", 0));
foodList.add(new FoodItem(R.drawable.d, "d", 0));
foodList.add(new FoodItem(R.drawable.e, "e", 0));
foodList.add(new FoodItem(R.drawable.f, "f", 0));
foodList.add(new FoodItem(R.drawable.g, "g", 0));
foodList.add(new FoodItem(R.drawable.h, "h", 0));
foodList.add(new FoodItem(R.drawable.i, "i", 0));
foodList.add(new FoodItem(R.drawable.j, "j", 0));
foodList.add(new FoodItem(R.drawable.k, "k", 0));
foodList.add(new FoodItem(R.drawable.l, "n", 0));
foodList.add(new FoodItem(R.drawable.m, "m", 0));
}
private void buildRecyclerView() {
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
adapter = new FoodAdapter(foodList);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
}
}
You need to use add the OnRatingBarChangeListener
to handle the OnRatingBarChanged
event.
Add the necesary code to the onBindViewHolder
method:
@Override
public void onBindViewHolder(@NonNull FoodViewHolder foodViewHolder, int i) {
FoodItem currentItem = arrayList.get(i);
foodViewHolder.viewHolderImageView.setImageResource(currentItem.getFoodImage());
foodViewHolder.viewHolderTextView.setText(currentItem.getFoodName());
foodViewHolder.viewHolderRatigBar.setRating(currentItem.getFoodRating());
foodViewHolder.viewHolderRatigBar.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener(){
@Override
public void onRatingBarChanged(RatingBar ratingBar, float rating, boolean fromUser){
currentItem.setFoodRating(rating);
}
}
}
NOTE:
The value "rating" passed to the onRatingBarChanged()
method is of type float
so you will need to change your FoodItem
class to accommodate this type.
If you wish to persist this value you will need to include some mechanism to save the new rating value--perhaps in a database.