This article will show you how to create ratingbar review that looks like rating on Google play store. As you know the user interface of review on Google Play store is great and full color.
To achieve rating look like Google Play Store, you have to know the formula of count rating view (especially for create rating that shown with color)
For create the icon of rating (icon star), you can use several library, but in this article I use library Zhanghai Material RatingBar.
Oh, In this article I also use Firebase Firestore as database to store the data of product and the reviews of product.
Create project in Firebase
Open Firebase Console and create new project. You also can use the existing project in Firebase. After that download the google-services.json then place it on directory app in your project.
Here I created data of product in Firebase Firestore manually :
![]() |
The sample product the created manually |
The data above will displayed on mobile android, and then from android we will send the review of this product.
Create Android Studio Project
After the sample data in Firebase has created, now we crate the android application to display the sample data and send review that data.
Gradle Configuration
In this project, I use some libraries that support the application, you can see at the following gradle :
build.gradle (Project:RatingGooglePlayStore)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Top-level build file where you can add configuration options common to all sub-projects/modules. | |
buildscript { | |
repositories { | |
google() | |
jcenter() | |
} | |
dependencies { | |
classpath 'com.android.tools.build:gradle:3.1.2' | |
//add this line | |
classpath 'com.google.gms:google-services:3.3.1' | |
// NOTE: Do not place your application dependencies here; they belong | |
// in the individual module build.gradle files | |
} | |
} | |
allprojects { | |
repositories { | |
google() | |
jcenter() | |
} | |
} | |
task clean(type: Delete) { | |
delete rootProject.buildDir | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.putuguna.ratinggoogleplaystore"
minSdkVersion 15
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
targetCompatibility 1.8
sourceCompatibility 1.8
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation "com.android.support:cardview-v7:27.1.1"
implementation "com.jakewharton:butterknife:8.8.1"
implementation 'com.android.support:support-v4:27.1.1'
annotationProcessor "com.jakewharton:butterknife-compiler:8.8.1"
implementation "com.android.support:recyclerview-v7:27.1.1"
implementation 'me.zhanghai.android.materialratingbar:library:1.0.2'
implementation 'com.google.firebase:firebase-core:15.0.2'
implementation "com.google.firebase:firebase-firestore:15.0.0"
implementation 'com.google.code.gson:gson:2.8.1'
}
apply plugin: 'com.google.gms.google-services'
Create Page Product
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
apply plugin: 'com.android.application' | |
android { | |
compileSdkVersion 27 | |
defaultConfig { | |
applicationId "com.putuguna.ratinggoogleplaystore" | |
minSdkVersion 15 | |
targetSdkVersion 27 | |
versionCode 1 | |
versionName "1.0" | |
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" | |
} | |
buildTypes { | |
release { | |
minifyEnabled false | |
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' | |
} | |
} | |
compileOptions { | |
targetCompatibility 1.8 | |
sourceCompatibility 1.8 | |
} | |
} | |
dependencies { | |
implementation fileTree(dir: 'libs', include: ['*.jar']) | |
implementation 'com.android.support:appcompat-v7:27.1.1' | |
implementation 'com.android.support.constraint:constraint-layout:1.1.0' | |
testImplementation 'junit:junit:4.12' | |
androidTestImplementation 'com.android.support.test:runner:1.0.2' | |
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' | |
implementation "com.android.support:cardview-v7:27.1.1" | |
implementation "com.jakewharton:butterknife:8.8.1" | |
implementation 'com.android.support:support-v4:27.1.1' | |
annotationProcessor "com.jakewharton:butterknife-compiler:8.8.1" | |
implementation "com.android.support:recyclerview-v7:27.1.1" | |
implementation 'me.zhanghai.android.materialratingbar:library:1.0.2' | |
implementation 'com.google.firebase:firebase-core:15.0.2' | |
implementation "com.google.firebase:firebase-firestore:15.0.0" | |
implementation 'com.google.code.gson:gson:2.8.1' | |
} | |
apply plugin: 'com.google.gms.google-services' |
The first page that will appears is page Product (MainActivity). In this page, the data that created manually in Firebase will displayed.
Recommended : Take image from gallery or camera using EasyImage Library
First, we create the model (object) that will handle the data from Firebase Firestore, here it is
ProductModel.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.putuguna.ratinggoogleplaystore.reviews; | |
public class ProductModel { | |
private String idProduct; | |
private int totalVoters; | |
private double totalRating; | |
private int star1; | |
private int star2; | |
private int star3; | |
private int star4; | |
private int star5; | |
private String productName; | |
public ProductModel(int totalVoters, double totalRating, int star1, int star2, int star3, int star4, int star5, String productName) { | |
this.totalVoters = totalVoters; | |
this.totalRating = totalRating; | |
this.star1 = star1; | |
this.star2 = star2; | |
this.star3 = star3; | |
this.star4 = star4; | |
this.star5 = star5; | |
this.productName = productName; | |
} | |
public ProductModel() { | |
} | |
public String getProductName() { | |
return productName; | |
} | |
public void setProductName(String productName) { | |
this.productName = productName; | |
} | |
public String getIdProduct() { | |
return idProduct; | |
} | |
public void setIdProduct(String idProduct) { | |
this.idProduct = idProduct; | |
} | |
public int getTotalVoters() { | |
return totalVoters; | |
} | |
public void setTotalVoters(int totalVoters) { | |
this.totalVoters = totalVoters; | |
} | |
public double getTotalRating() { | |
return totalRating; | |
} | |
public void setTotalRating(double totalRating) { | |
this.totalRating = totalRating; | |
} | |
public int getStar1() { | |
return star1; | |
} | |
public void setStar1(int star1) { | |
this.star1 = star1; | |
} | |
public int getStar2() { | |
return star2; | |
} | |
public void setStar2(int star2) { | |
this.star2 = star2; | |
} | |
public int getStar3() { | |
return star3; | |
} | |
public void setStar3(int star3) { | |
this.star3 = star3; | |
} | |
public int getStar4() { | |
return star4; | |
} | |
public void setStar4(int star4) { | |
this.star4 = star4; | |
} | |
public int getStar5() { | |
return star5; | |
} | |
public void setStar5(int star5) { | |
this.star5 = star5; | |
} | |
} |
item_product.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
xmlns:app="http://schemas.android.com/apk/res-auto" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:orientation="vertical"> | |
<android.support.v7.widget.CardView | |
android:id="@+id/cv_item" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content"> | |
<LinearLayout | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:padding="10dp" | |
android:orientation="vertical"> | |
<TextView | |
android:id="@+id/tv_product_name" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:layout_gravity="center" | |
android:gravity="center" | |
android:textSize="18sp" | |
android:textStyle="bold" | |
tools:text="Product Name"/> | |
<me.zhanghai.android.materialratingbar.MaterialRatingBar | |
android:id="@+id/total_star_rating" | |
style="@style/Widget.MaterialRatingBar.RatingBar" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_gravity="center" | |
android:layout_marginBottom="@dimen/margin_value_5dp" | |
android:layout_marginTop="@dimen/margin_value_5dp" | |
android:isIndicator="true" | |
android:maxHeight="20dp" | |
android:minHeight="20dp" | |
android:numStars="5" | |
android:stepSize="0.25" | |
app:mrb_progressBackgroundTint="@color/colorPrimary" | |
app:mrb_progressTint="@color/colorPrimary" | |
app:mrb_secondaryProgressTint="@color/colorPrimary" /> | |
</LinearLayout> | |
</android.support.v7.widget.CardView> | |
</LinearLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.putuguna.ratinggoogleplaystore.product; | |
import android.support.annotation.NonNull; | |
import android.support.v7.widget.CardView; | |
import android.support.v7.widget.RecyclerView; | |
import android.view.LayoutInflater; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.widget.TextView; | |
import com.google.gson.Gson; | |
import com.putuguna.ratinggoogleplaystore.R; | |
import com.putuguna.ratinggoogleplaystore.reviews.ProductModel; | |
import java.util.List; | |
import butterknife.BindView; | |
import butterknife.ButterKnife; | |
import me.zhanghai.android.materialratingbar.MaterialRatingBar; | |
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductHolder> { | |
public interface OnClickListenerAdapter { | |
void onItemClicked(String product); | |
} | |
private OnClickListenerAdapter onClickListenerAdapter; | |
private List<ProductModel> listProductModel; | |
public ProductAdapter(List<ProductModel> listProductModel) { | |
this.listProductModel = listProductModel; | |
} | |
@NonNull | |
@Override | |
public ProductHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { | |
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_product, parent, false); | |
return new ProductHolder(view); | |
} | |
@Override | |
public void onBindViewHolder(@NonNull ProductHolder holder, int position) { | |
ProductModel model = listProductModel.get(position); | |
holder.totalStarRating.setRating(Float.parseFloat(String.valueOf(model.getTotalRating()))); | |
holder.tvProductName.setText(model.getProductName()); | |
holder.cvItem.setOnClickListener(v -> { | |
if (onClickListenerAdapter != null) { | |
onClickListenerAdapter.onItemClicked(new Gson().toJson(model)); | |
} | |
}); | |
} | |
@Override | |
public int getItemCount() { | |
return listProductModel.size(); | |
} | |
public void setOnClickListenerAdapter(OnClickListenerAdapter onClickListenerAdapter) { | |
this.onClickListenerAdapter = onClickListenerAdapter; | |
} | |
public class ProductHolder extends RecyclerView.ViewHolder { | |
@BindView(R.id.tv_product_name) | |
TextView tvProductName; | |
@BindView(R.id.total_star_rating) | |
MaterialRatingBar totalStarRating; | |
@BindView(R.id.cv_item) | |
CardView cvItem; | |
public ProductHolder(View itemView) { | |
super(itemView); | |
ButterKnife.bind(this, itemView); | |
} | |
} | |
} |
MainActivity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.putuguna.ratinggoogleplaystore.product; | |
import android.app.ProgressDialog; | |
import android.os.Bundle; | |
import android.support.annotation.NonNull; | |
import android.support.annotation.Nullable; | |
import android.support.v7.app.AppCompatActivity; | |
import android.support.v7.widget.LinearLayoutManager; | |
import android.support.v7.widget.RecyclerView; | |
import android.widget.Toast; | |
import com.google.android.gms.tasks.OnCompleteListener; | |
import com.google.android.gms.tasks.OnFailureListener; | |
import com.google.android.gms.tasks.OnSuccessListener; | |
import com.google.android.gms.tasks.Task; | |
import com.google.firebase.firestore.CollectionReference; | |
import com.google.firebase.firestore.DocumentReference; | |
import com.google.firebase.firestore.DocumentSnapshot; | |
import com.google.firebase.firestore.FirebaseFirestore; | |
import com.google.firebase.firestore.QuerySnapshot; | |
import com.putuguna.ratinggoogleplaystore.R; | |
import com.putuguna.ratinggoogleplaystore.reviews.ProductModel; | |
import com.putuguna.ratinggoogleplaystore.reviews.ReviewActivity; | |
import java.util.ArrayList; | |
import java.util.List; | |
import butterknife.BindView; | |
import butterknife.ButterKnife; | |
public class MainActivity extends AppCompatActivity implements ProductAdapter.OnClickListenerAdapter { | |
@BindView(R.id.rv_product) | |
RecyclerView rvProduct; | |
private ProductAdapter adapter; | |
private FirebaseFirestore firebaseFirestore = FirebaseFirestore.getInstance(); | |
ProgressDialog progressDialog ; | |
@Override | |
protected void onCreate(@Nullable Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
ButterKnife.bind(this); | |
initView(); | |
getProduct(); | |
} | |
private void initView(){ | |
progressDialog = new ProgressDialog(this); | |
progressDialog.setMessage("Load data product ..."); | |
progressDialog.show(); | |
} | |
private void getProduct(){ | |
CollectionReference collectionReference = firebaseFirestore.collection("product"); | |
collectionReference.get() | |
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() { | |
@Override | |
public void onSuccess(QuerySnapshot queryDocumentSnapshots) { | |
progressDialog.dismiss(); | |
if(!queryDocumentSnapshots.isEmpty()){ | |
List<ProductModel> list = new ArrayList<>(); | |
for(DocumentSnapshot document : queryDocumentSnapshots){ | |
ProductModel productModel = document.toObject(ProductModel.class); | |
list.add(productModel); | |
} | |
initListProduct(list); | |
}else{ | |
Toast.makeText(MainActivity.this, "Product is empty", Toast.LENGTH_SHORT).show(); | |
} | |
} | |
}) | |
.addOnFailureListener(new OnFailureListener() { | |
@Override | |
public void onFailure(@NonNull Exception e) { | |
Toast.makeText(MainActivity.this, "Failed : "+e.getMessage(), Toast.LENGTH_SHORT).show(); | |
progressDialog.dismiss(); | |
} | |
}); | |
} | |
private void initListProduct(List<ProductModel> productModelList){ | |
adapter = new ProductAdapter(productModelList); | |
rvProduct.setLayoutManager(new LinearLayoutManager(this)); | |
adapter.setOnClickListenerAdapter(this); | |
rvProduct.setAdapter(adapter); | |
} | |
@Override | |
protected void onResume() { | |
super.onResume(); | |
getProduct(); | |
} | |
@Override | |
public void onItemClicked(String product) { | |
ReviewActivity.start(this, product); | |
} | |
} |
![]() |
The data that I created manually in firebase has displayed on mobile |
Create Page Review
After the product has displayed, now we create page review that display the rating, insert review and displaying review.
ReviewModel.java
This class use to handle data of review data got from Firebase Firestore, here is the code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.putuguna.ratinggoogleplaystore.reviews; | |
import java.util.Date; | |
public class ReviewModel { | |
private String name; | |
private String review; | |
private Date timeStamp; | |
private double totalStarGiven; | |
public ReviewModel(String name, String review, Date timeStamp, double totalStarGiven) { | |
this.name = name; | |
this.review = review; | |
this.timeStamp = timeStamp; | |
this.totalStarGiven = totalStarGiven; | |
} | |
public ReviewModel() { | |
} | |
public String getName() { | |
return name; | |
} | |
public void setName(String name) { | |
this.name = name; | |
} | |
public String getReview() { | |
return review; | |
} | |
public void setReview(String review) { | |
this.review = review; | |
} | |
public Date getTimeStamp() { | |
return timeStamp; | |
} | |
public void setTimeStamp(Date timeStamp) { | |
this.timeStamp = timeStamp; | |
} | |
public double getTotalStarGiven() { | |
return totalStarGiven; | |
} | |
public void setTotalStarGiven(double totalStarGiven) { | |
this.totalStarGiven = totalStarGiven; | |
} | |
} |
item_review.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout 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="wrap_content" | |
android:layout_margin="@dimen/margin_value_10dp" | |
android:orientation="vertical"> | |
<LinearLayout | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:orientation="horizontal"> | |
<LinearLayout | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:orientation="vertical"> | |
<LinearLayout | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:orientation="horizontal"> | |
<TextView | |
android:id="@+id/tv_nama_pasien" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_gravity="center" | |
android:layout_marginLeft="@dimen/margin_value_10dp" | |
android:layout_marginRight="@dimen/margin_value_10dp" | |
android:textStyle="bold" | |
tools:text="Nama Pasien" /> | |
<me.zhanghai.android.materialratingbar.MaterialRatingBar | |
android:id="@+id/total_star_rating" | |
style="@style/Widget.MaterialRatingBar.RatingBar" | |
android:layout_width="wrap_content" | |
android:layout_height="15dp" | |
android:layout_gravity="center" | |
android:layout_marginBottom="@dimen/margin_value_5dp" | |
android:layout_marginTop="@dimen/margin_value_5dp" | |
android:isIndicator="true" | |
android:maxHeight="20dp" | |
android:minHeight="20dp" | |
android:numStars="5" | |
android:stepSize="0.25" | |
app:mrb_progressBackgroundTint="@color/colorPrimary" | |
app:mrb_progressTint="@color/colorPrimary" | |
app:mrb_secondaryProgressTint="@color/colorPrimary" /> | |
</LinearLayout> | |
<TextView | |
android:id="@+id/tv_tgl_rating" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:layout_marginLeft="@dimen/margin_value_10dp" | |
android:textSize="10sp" | |
android:textStyle="bold" | |
tools:text="12:23:34"/> | |
<TextView | |
android:id="@+id/tv_desc_review" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:layout_marginLeft="@dimen/margin_value_10dp" | |
tools:text="Lambat!!! apa yang saya minta selalu saya dapatkan dan tidak pernah buruk pelayanannya, Good Job ya" /> | |
<View | |
android:layout_width="match_parent" | |
android:layout_height="1dp" | |
android:layout_marginLeft="@dimen/margin_value_10dp" | |
android:layout_marginRight="@dimen/margin_value_10dp" | |
android:layout_marginTop="@dimen/margin_value_10dp" | |
android:background="@android:color/darker_gray" /> | |
</LinearLayout> | |
</LinearLayout> | |
</LinearLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.putuguna.ratinggoogleplaystore.reviews; | |
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.TextView; | |
import com.putuguna.ratinggoogleplaystore.R; | |
import java.util.List; | |
import butterknife.BindView; | |
import butterknife.ButterKnife; | |
import me.zhanghai.android.materialratingbar.MaterialRatingBar; | |
public class ReviewAdapter extends RecyclerView.Adapter<ReviewAdapter.ReviewViewHolder> { | |
private List<ReviewModel> listReview; | |
public ReviewAdapter(List<ReviewModel> listReview) { | |
this.listReview = listReview; | |
} | |
@NonNull | |
@Override | |
public ReviewViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { | |
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_review, parent, false); | |
return new ReviewViewHolder(view); | |
} | |
@Override | |
public void onBindViewHolder(@NonNull ReviewViewHolder holder, int position) { | |
ReviewModel model = listReview.get(position); | |
holder.totalStarRating.setRating(Float.parseFloat(String.valueOf(model.getTotalStarGiven()))); | |
holder.tvDescReview.setText(model.getReview()); | |
holder.tvTglRating.setText(String.valueOf(model.getTimeStamp())); | |
holder.tvNamaPasien.setText(model.getName()); | |
} | |
@Override | |
public int getItemCount() { | |
return listReview.size(); | |
} | |
public class ReviewViewHolder extends RecyclerView.ViewHolder { | |
@BindView(R.id.tv_nama_pasien) | |
TextView tvNamaPasien; | |
@BindView(R.id.total_star_rating) | |
MaterialRatingBar totalStarRating; | |
@BindView(R.id.tv_tgl_rating) | |
TextView tvTglRating; | |
@BindView(R.id.tv_desc_review) | |
TextView tvDescReview; | |
public ReviewViewHolder(View itemView) { | |
super(itemView); | |
ButterKnife.bind(this, itemView); | |
} | |
} | |
} |
![]() |
Rating using stars and colors |
To achieve the goal like the image above, there are several process that you have to do :
1. Insert Review To Firestore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Insert data review to collection of product | |
* @param review | |
*/ | |
private void insertDataReview(ReviewModel review) { | |
ReviewModel reviewModel = new ReviewModel(review.getName(), review.getReview(), review.getTimeStamp(), review.getTotalStarGiven()); | |
CollectionReference collectionReference = firebaseFirestore.collection("product"); | |
DocumentReference documentReference = collectionReference.document(productModelGlobal.getIdProduct()); | |
documentReference.collection("review") | |
.add(reviewModel) | |
.addOnSuccessListener(documentReference1 -> { | |
progressDialog.dismiss(); | |
//after success, then update the rating in product | |
updateRating(review, productModelGlobal); | |
}) | |
.addOnFailureListener(new OnFailureListener() { | |
@Override | |
public void onFailure(@NonNull Exception e) { | |
progressDialog.dismiss(); | |
Toast.makeText(ReviewActivity.this, "Failed : " + e.getMessage(), Toast.LENGTH_SHORT).show(); | |
} | |
}); | |
} |
![]() |
Data review has stored into Firebase Firestore |
Recommended : How to insert and display file image from Firebase Firestore
After data review stored successfully, the update the rating in product
2. Update Rating Product
The following code will update the rating in data product, after that will change the display of rating view and rating color.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* this method used to update rating of product | |
* | |
* @param reviewModel | |
* @param productModel | |
*/ | |
private void updateRating(ReviewModel reviewModel, ProductModel productModel) { | |
ProductModel rate = new ProductModel(); | |
rate.setIdProduct(productModel.getIdProduct()); | |
rate.setProductName(productModel.getProductName()); | |
//update stars | |
double totalStars; | |
int totalVoters = 0; | |
if (reviewModel.getTotalStarGiven() == 1.0) { | |
totalStars = 1.0 + (double) productModel.getStar1(); | |
rate.setStar1((int) totalStars); | |
rate.setStar2(productModel.getStar2()); | |
rate.setStar3(productModel.getStar3()); | |
rate.setStar4(productModel.getStar4()); | |
rate.setStar5(productModel.getStar5()); | |
totalVoters = (int) (totalStars + productModel.getStar2() + productModel.getStar3() + productModel.getStar4() + productModel.getStar5()); | |
if (productModel.getTotalVoters() == 0) { | |
rate.setTotalVoters(1); | |
} else { | |
rate.setTotalVoters(totalVoters); | |
} | |
} else if (reviewModel.getTotalStarGiven() == 2.0) { | |
totalStars = 1.0 + (double) productModel.getStar2(); | |
rate.setStar1(productModel.getStar1()); | |
rate.setStar2((int) totalStars); | |
rate.setStar3(productModel.getStar3()); | |
rate.setStar4(productModel.getStar4()); | |
rate.setStar5(productModel.getStar5()); | |
totalVoters = (int) (totalStars + productModel.getStar1() + productModel.getStar3() + productModel.getStar4() + productModel.getStar5()); | |
if (productModel.getTotalVoters() == 0) { | |
rate.setTotalVoters(1); | |
} else { | |
rate.setTotalVoters(totalVoters); | |
} | |
} else if (reviewModel.getTotalStarGiven() == 3.0) { | |
totalStars = 1.0 + (double) productModel.getStar3(); | |
rate.setStar1(productModel.getStar1()); | |
rate.setStar2(productModel.getStar2()); | |
rate.setStar3((int) totalStars); | |
rate.setStar4(productModel.getStar4()); | |
rate.setStar5(productModel.getStar5()); | |
totalVoters = (int) (totalStars + productModel.getStar1() + productModel.getStar2() + productModel.getStar4() + productModel.getStar5()); | |
if (productModel.getTotalVoters() == 0) { | |
rate.setTotalVoters(1); | |
} else { | |
rate.setTotalVoters(totalVoters); | |
} | |
} else if (reviewModel.getTotalStarGiven() == 4.0) { | |
totalStars = 1.0 + (double) productModel.getStar4(); | |
rate.setStar1(productModel.getStar1()); | |
rate.setStar2(productModel.getStar2()); | |
rate.setStar3(productModel.getStar3()); | |
rate.setStar4((int) totalStars); | |
rate.setStar5(productModel.getStar5()); | |
totalVoters = (int) (totalStars + productModel.getStar1() + productModel.getStar2() + productModel.getStar3() + productModel.getStar5()); | |
if (productModel.getTotalVoters() == 0) { | |
rate.setTotalVoters(1); | |
} else { | |
rate.setTotalVoters(totalVoters); | |
} | |
} else if (reviewModel.getTotalStarGiven() == 5.0) { | |
totalStars = 1.0 + (double) productModel.getStar5(); | |
rate.setStar1(productModel.getStar1()); | |
rate.setStar2(productModel.getStar2()); | |
rate.setStar3(productModel.getStar3()); | |
rate.setStar4(productModel.getStar4()); | |
rate.setStar5((int) totalStars); | |
totalVoters = (int) (totalStars + productModel.getStar1() + productModel.getStar2() + productModel.getStar3() + productModel.getStar4()); | |
if (productModel.getTotalVoters() == 0) { | |
rate.setTotalVoters(1); | |
} else { | |
rate.setTotalVoters(totalVoters); | |
} | |
} | |
//update rate | |
int totalStar1 = rate.getStar1() * 1; | |
int totalStar2 = rate.getStar2() * 2; | |
int totalStar3 = rate.getStar3() * 3; | |
int totalStar4 = rate.getStar4() * 4; | |
int totalStar5 = rate.getStar5() * 5; | |
double sumOfStars = totalStar1 + totalStar2 + totalStar3 + totalStar4 + totalStar5; | |
double totalRating = sumOfStars / (double) totalVoters; | |
DecimalFormat format = new DecimalFormat(".#"); | |
rate.setTotalRating(Double.parseDouble(format.format(totalRating))); | |
CollectionReference collectionReference = firebaseFirestore.collection("product"); | |
collectionReference.document(productModel.getIdProduct()) | |
.set(rate) | |
.addOnSuccessListener(aVoid -> { | |
progressDialog.dismiss(); | |
Toast.makeText(ReviewActivity.this, "Successfully update Rating", Toast.LENGTH_SHORT).show(); | |
productModelGlobal = rate; | |
//after success, then update the rating color and populate the recyclerview with the data of reviews | |
setRatingByColor(rate); | |
getAllReview(productModel.getIdProduct()); | |
}) | |
.addOnFailureListener(new OnFailureListener() { | |
@Override | |
public void onFailure(@NonNull Exception e) { | |
progressDialog.dismiss(); | |
Toast.makeText(ReviewActivity.this, "Failed Update Rating : " + e.getMessage(), Toast.LENGTH_SHORT).show(); | |
} | |
}); | |
} |
3. Update the rating color
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This method used to display rating by colors | |
* | |
* @param productModel | |
*/ | |
private void setRatingByColor(ProductModel productModel) { | |
int widthView = constrainLayout1.getWidth(); | |
int totalAllVoters = productModel.getTotalVoters(); | |
int totalRateStar1 = productModel.getStar1(); | |
int totalRateStar2 = productModel.getStar2(); | |
int totalRateStar3 = productModel.getStar3(); | |
int totalRateStar4 = productModel.getStar4(); | |
int totalRateStar5 = productModel.getStar5(); | |
//convert to double | |
double votersInDouble = (double) totalAllVoters; | |
//RATING STAR 1 | |
double star1 = (double) totalRateStar1; | |
double sum1 = (star1 / votersInDouble); | |
int rating1 = (int) (sum1 * widthView); | |
ConstraintLayout.LayoutParams layoutParams1 = new ConstraintLayout.LayoutParams(rating1, ConstraintLayout.LayoutParams.MATCH_PARENT); | |
layoutParams1.setMargins(0, 5, 0, 5); | |
llPercentage1.setBackgroundColor(Color.parseColor("#ff6f31")); | |
llPercentage1.setLayoutParams(layoutParams1); | |
//RATING STAR 2 | |
double star2 = (double) totalRateStar2; | |
double sum2 = (star2 / votersInDouble); | |
int rating2 = (int) (sum2 * widthView); | |
ConstraintLayout.LayoutParams layoutParams2 = new ConstraintLayout.LayoutParams(rating2, ConstraintLayout.LayoutParams.MATCH_PARENT); | |
layoutParams2.setMargins(0, 5, 0, 5); | |
llPercentage2.setBackgroundColor(Color.parseColor("#ff9f02")); | |
llPercentage2.setLayoutParams(layoutParams2); | |
//RATING STAR 3 | |
double star3 = (double) totalRateStar3; | |
double sum3 = (star3 / votersInDouble); | |
int rating3 = (int) (sum3 * widthView); | |
ConstraintLayout.LayoutParams layoutParams3 = new ConstraintLayout.LayoutParams(rating3, ConstraintLayout.LayoutParams.MATCH_PARENT); | |
layoutParams3.setMargins(0, 5, 0, 5); | |
llPercentage3.setBackgroundColor(Color.parseColor("#ffcf02")); | |
llPercentage3.setLayoutParams(layoutParams3); | |
//RATING STAR 4 | |
double star4 = (double) totalRateStar4; | |
double sum4 = (star4 / votersInDouble); | |
int rating4 = (int) (sum4 * widthView); | |
ConstraintLayout.LayoutParams layoutParams4 = new ConstraintLayout.LayoutParams(rating4, ConstraintLayout.LayoutParams.MATCH_PARENT); | |
layoutParams4.setMargins(0, 5, 0, 5); | |
llPercentage4.setBackgroundColor(Color.parseColor("#9ace6a")); | |
llPercentage4.setLayoutParams(layoutParams4); | |
//RATING STAR 5 | |
double star5 = (double) totalRateStar5; | |
double sum5 = (star5 / votersInDouble); | |
int rating5 = (int) (sum5 * widthView); | |
ConstraintLayout.LayoutParams layoutParams5 = new ConstraintLayout.LayoutParams(rating5, ConstraintLayout.LayoutParams.MATCH_PARENT); | |
layoutParams5.setMargins(0, 5, 0, 5); | |
llPercentage5.setBackgroundColor(Color.parseColor("#57bb8a")); | |
llPercentage5.setLayoutParams(layoutParams5); | |
// menampilkan rating berdasarkan angka | |
int totalBintangSatu = totalRateStar1 * 1; | |
int totalBintangDua = totalRateStar2 * 2; | |
int totalBintangTiga = totalRateStar3 * 3; | |
int totalBintangEmpat = totalRateStar4 * 5; | |
int totalBintangLima = totalRateStar5 * 5; | |
double sumBintang = totalBintangSatu + | |
totalBintangDua + | |
totalBintangTiga + | |
totalBintangEmpat + | |
totalBintangLima; | |
double rating = (sumBintang / votersInDouble); | |
DecimalFormat format = new DecimalFormat(".#"); | |
tvTotalNumberRating.setText(String.valueOf(format.format(rating))); | |
totalStarRating.setRating(Float.parseFloat(String.valueOf(rating))); | |
tvTotalPemberiBintang.setText(String.valueOf(totalAllVoters) + " total"); | |
} |
4. Populating the recyclerview with data of reviews
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* the method used to get all reviews in firebase firestore | |
* @param idProduct | |
*/ | |
private void getAllReview(String idProduct) { | |
progressBar.setVisibility(View.VISIBLE); | |
rvReview.setVisibility(View.GONE); | |
CollectionReference collectionReference = firebaseFirestore.collection("product"); | |
DocumentReference documentReference = collectionReference.document(idProduct); | |
documentReference.collection("review") | |
.get() | |
.addOnCompleteListener(task -> { | |
progressBar.setVisibility(View.GONE); | |
rvReview.setVisibility(View.VISIBLE); | |
if (task.getResult().isEmpty()) { | |
} else if (task.isSuccessful()) { | |
List<ReviewModel> listReview = new ArrayList<>(); | |
for (DocumentSnapshot documentSnapshot : task.getResult()) { | |
ReviewModel reviewModel = new ReviewModel(); | |
try { | |
reviewModel.setName(documentSnapshot.get("name").toString()); | |
reviewModel.setReview(documentSnapshot.get("review").toString()); | |
reviewModel.setTimeStamp(new Date(documentSnapshot.get("timeStamp").toString())); | |
reviewModel.setTotalStarGiven(Double.parseDouble(documentSnapshot.get("totalStarGiven").toString())); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
listReview.add(reviewModel); | |
initListReview(listReview); | |
} | |
} | |
}) | |
.addOnFailureListener(new OnFailureListener() { | |
@Override | |
public void onFailure(@NonNull Exception e) { | |
} | |
}); | |
} | |
//this method used to populating the recyclerview with data of reviews | |
private void initListReview(List<ReviewModel> reviewModels) { | |
adapter = new ReviewAdapter(reviewModels); | |
rvReview.setLayoutManager(new LinearLayoutManager(this)); | |
rvReview.setAdapter(adapter); | |
} |
Recommended : Insert image from android to database (server using PHP & MySQL)
Here is the full code of ReviewActivity.java :
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.putuguna.ratinggoogleplaystore.reviews; | |
import android.app.Dialog; | |
import android.app.ProgressDialog; | |
import android.content.Context; | |
import android.content.Intent; | |
import android.graphics.Color; | |
import android.graphics.drawable.ColorDrawable; | |
import android.os.Bundle; | |
import android.os.Handler; | |
import android.support.annotation.NonNull; | |
import android.support.constraint.ConstraintLayout; | |
import android.support.v7.app.AppCompatActivity; | |
import android.support.v7.widget.LinearLayoutManager; | |
import android.support.v7.widget.RecyclerView; | |
import android.text.TextUtils; | |
import android.view.Menu; | |
import android.view.MenuInflater; | |
import android.view.MenuItem; | |
import android.view.View; | |
import android.view.Window; | |
import android.widget.Button; | |
import android.widget.EditText; | |
import android.widget.LinearLayout; | |
import android.widget.ProgressBar; | |
import android.widget.TextView; | |
import android.widget.Toast; | |
import com.google.android.gms.tasks.OnCompleteListener; | |
import com.google.android.gms.tasks.OnFailureListener; | |
import com.google.android.gms.tasks.OnSuccessListener; | |
import com.google.android.gms.tasks.Task; | |
import com.google.firebase.firestore.CollectionReference; | |
import com.google.firebase.firestore.DocumentReference; | |
import com.google.firebase.firestore.DocumentSnapshot; | |
import com.google.firebase.firestore.FirebaseFirestore; | |
import com.google.firebase.firestore.QuerySnapshot; | |
import com.google.gson.Gson; | |
import com.putuguna.ratinggoogleplaystore.R; | |
import java.text.DecimalFormat; | |
import java.util.ArrayList; | |
import java.util.Date; | |
import java.util.List; | |
import butterknife.BindView; | |
import butterknife.ButterKnife; | |
import me.zhanghai.android.materialratingbar.MaterialRatingBar; | |
public class ReviewActivity extends AppCompatActivity { | |
public static String EXTRA_PRODUCT_MODEL = "EXTRA_PRODUCT_MODEL"; | |
@BindView(R.id.tv_total_number_rating) | |
TextView tvTotalNumberRating; | |
@BindView(R.id.total_star_rating) | |
MaterialRatingBar totalStarRating; | |
@BindView(R.id.tv_total_pemberi_bintang) | |
TextView tvTotalPemberiBintang; | |
@BindView(R.id.ll_percentage_5) | |
LinearLayout llPercentage5; | |
@BindView(R.id.constrain_layout_5) | |
ConstraintLayout constrainLayout5; | |
@BindView(R.id.ll_percentage_4) | |
LinearLayout llPercentage4; | |
@BindView(R.id.constrain_layout_4) | |
ConstraintLayout constrainLayout4; | |
@BindView(R.id.ll_percentage_3) | |
LinearLayout llPercentage3; | |
@BindView(R.id.constrain_layout_3) | |
ConstraintLayout constrainLayout3; | |
@BindView(R.id.ll_percentage_2) | |
LinearLayout llPercentage2; | |
@BindView(R.id.constrain_layout_2) | |
ConstraintLayout constrainLayout2; | |
@BindView(R.id.ll_percentage_1) | |
LinearLayout llPercentage1; | |
@BindView(R.id.constrain_layout_1) | |
ConstraintLayout constrainLayout1; | |
@BindView(R.id.progressbar) | |
ProgressBar progressBar; | |
@BindView(R.id.rv_review) | |
RecyclerView rvReview; | |
private ProgressDialog progressDialog; | |
private Handler handler = new Handler(); | |
private ProductModel productModelGlobal; | |
private FirebaseFirestore firebaseFirestore = FirebaseFirestore.getInstance(); | |
private ReviewAdapter adapter; | |
public static void start(Context context, String productModel) { | |
Intent starter = new Intent(context, ReviewActivity.class); | |
starter.putExtra(EXTRA_PRODUCT_MODEL, productModel); | |
context.startActivity(starter); | |
} | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_review); | |
ButterKnife.bind(this); | |
initView(); | |
} | |
private void initView() { | |
progressDialog = new ProgressDialog(this); | |
productModelGlobal = new Gson().fromJson(getIntent().getStringExtra(EXTRA_PRODUCT_MODEL), ProductModel.class); | |
//this method used to get the width of view | |
progressDialog.setMessage("Count Width Of View"); | |
progressDialog.show(); | |
handler.postDelayed(new Runnable() { | |
@Override | |
public void run() { | |
progressDialog.dismiss(); | |
setRatingByColor(productModelGlobal); | |
getAllReview(productModelGlobal.getIdProduct()); | |
} | |
}, 3000); | |
} | |
/** | |
* Insert data review to collection of product | |
* @param review | |
*/ | |
private void insertDataReview(ReviewModel review) { | |
ReviewModel reviewModel = new ReviewModel(review.getName(), review.getReview(), review.getTimeStamp(), review.getTotalStarGiven()); | |
CollectionReference collectionReference = firebaseFirestore.collection("product"); | |
DocumentReference documentReference = collectionReference.document(productModelGlobal.getIdProduct()); | |
documentReference.collection("review") | |
.add(reviewModel) | |
.addOnSuccessListener(documentReference1 -> { | |
progressDialog.dismiss(); | |
//after success, then update the rating in product | |
updateRating(review, productModelGlobal); | |
}) | |
.addOnFailureListener(new OnFailureListener() { | |
@Override | |
public void onFailure(@NonNull Exception e) { | |
progressDialog.dismiss(); | |
Toast.makeText(ReviewActivity.this, "Failed : " + e.getMessage(), Toast.LENGTH_SHORT).show(); | |
} | |
}); | |
} | |
/** | |
* this method used to update rating of product | |
* | |
* @param reviewModel | |
* @param productModel | |
*/ | |
private void updateRating(ReviewModel reviewModel, ProductModel productModel) { | |
ProductModel rate = new ProductModel(); | |
rate.setIdProduct(productModel.getIdProduct()); | |
rate.setProductName(productModel.getProductName()); | |
//update stars | |
double totalStars; | |
int totalVoters = 0; | |
if (reviewModel.getTotalStarGiven() == 1.0) { | |
totalStars = 1.0 + (double) productModel.getStar1(); | |
rate.setStar1((int) totalStars); | |
rate.setStar2(productModel.getStar2()); | |
rate.setStar3(productModel.getStar3()); | |
rate.setStar4(productModel.getStar4()); | |
rate.setStar5(productModel.getStar5()); | |
totalVoters = (int) (totalStars + productModel.getStar2() + productModel.getStar3() + productModel.getStar4() + productModel.getStar5()); | |
if (productModel.getTotalVoters() == 0) { | |
rate.setTotalVoters(1); | |
} else { | |
rate.setTotalVoters(totalVoters); | |
} | |
} else if (reviewModel.getTotalStarGiven() == 2.0) { | |
totalStars = 1.0 + (double) productModel.getStar2(); | |
rate.setStar1(productModel.getStar1()); | |
rate.setStar2((int) totalStars); | |
rate.setStar3(productModel.getStar3()); | |
rate.setStar4(productModel.getStar4()); | |
rate.setStar5(productModel.getStar5()); | |
totalVoters = (int) (totalStars + productModel.getStar1() + productModel.getStar3() + productModel.getStar4() + productModel.getStar5()); | |
if (productModel.getTotalVoters() == 0) { | |
rate.setTotalVoters(1); | |
} else { | |
rate.setTotalVoters(totalVoters); | |
} | |
} else if (reviewModel.getTotalStarGiven() == 3.0) { | |
totalStars = 1.0 + (double) productModel.getStar3(); | |
rate.setStar1(productModel.getStar1()); | |
rate.setStar2(productModel.getStar2()); | |
rate.setStar3((int) totalStars); | |
rate.setStar4(productModel.getStar4()); | |
rate.setStar5(productModel.getStar5()); | |
totalVoters = (int) (totalStars + productModel.getStar1() + productModel.getStar2() + productModel.getStar4() + productModel.getStar5()); | |
if (productModel.getTotalVoters() == 0) { | |
rate.setTotalVoters(1); | |
} else { | |
rate.setTotalVoters(totalVoters); | |
} | |
} else if (reviewModel.getTotalStarGiven() == 4.0) { | |
totalStars = 1.0 + (double) productModel.getStar4(); | |
rate.setStar1(productModel.getStar1()); | |
rate.setStar2(productModel.getStar2()); | |
rate.setStar3(productModel.getStar3()); | |
rate.setStar4((int) totalStars); | |
rate.setStar5(productModel.getStar5()); | |
totalVoters = (int) (totalStars + productModel.getStar1() + productModel.getStar2() + productModel.getStar3() + productModel.getStar5()); | |
if (productModel.getTotalVoters() == 0) { | |
rate.setTotalVoters(1); | |
} else { | |
rate.setTotalVoters(totalVoters); | |
} | |
} else if (reviewModel.getTotalStarGiven() == 5.0) { | |
totalStars = 1.0 + (double) productModel.getStar5(); | |
rate.setStar1(productModel.getStar1()); | |
rate.setStar2(productModel.getStar2()); | |
rate.setStar3(productModel.getStar3()); | |
rate.setStar4(productModel.getStar4()); | |
rate.setStar5((int) totalStars); | |
totalVoters = (int) (totalStars + productModel.getStar1() + productModel.getStar2() + productModel.getStar3() + productModel.getStar4()); | |
if (productModel.getTotalVoters() == 0) { | |
rate.setTotalVoters(1); | |
} else { | |
rate.setTotalVoters(totalVoters); | |
} | |
} | |
//update rate | |
int totalStar1 = rate.getStar1() * 1; | |
int totalStar2 = rate.getStar2() * 2; | |
int totalStar3 = rate.getStar3() * 3; | |
int totalStar4 = rate.getStar4() * 4; | |
int totalStar5 = rate.getStar5() * 5; | |
double sumOfStars = totalStar1 + totalStar2 + totalStar3 + totalStar4 + totalStar5; | |
double totalRating = sumOfStars / (double) totalVoters; | |
DecimalFormat format = new DecimalFormat(".#"); | |
rate.setTotalRating(Double.parseDouble(format.format(totalRating))); | |
CollectionReference collectionReference = firebaseFirestore.collection("product"); | |
collectionReference.document(productModel.getIdProduct()) | |
.set(rate) | |
.addOnSuccessListener(aVoid -> { | |
progressDialog.dismiss(); | |
Toast.makeText(ReviewActivity.this, "Successfully update Rating", Toast.LENGTH_SHORT).show(); | |
productModelGlobal = rate; | |
setRatingByColor(rate); | |
getAllReview(productModel.getIdProduct()); | |
}) | |
.addOnFailureListener(new OnFailureListener() { | |
@Override | |
public void onFailure(@NonNull Exception e) { | |
progressDialog.dismiss(); | |
Toast.makeText(ReviewActivity.this, "Failed Update Rating : " + e.getMessage(), Toast.LENGTH_SHORT).show(); | |
} | |
}); | |
} | |
/** | |
* This method used to display rating by colors | |
* | |
* @param productModel | |
*/ | |
private void setRatingByColor(ProductModel productModel) { | |
int widthView = constrainLayout1.getWidth(); | |
int totalAllVoters = productModel.getTotalVoters(); | |
int totalRateStar1 = productModel.getStar1(); | |
int totalRateStar2 = productModel.getStar2(); | |
int totalRateStar3 = productModel.getStar3(); | |
int totalRateStar4 = productModel.getStar4(); | |
int totalRateStar5 = productModel.getStar5(); | |
//convert to double | |
double votersInDouble = (double) totalAllVoters; | |
//RATING STAR 1 | |
double star1 = (double) totalRateStar1; | |
double sum1 = (star1 / votersInDouble); | |
int rating1 = (int) (sum1 * widthView); | |
ConstraintLayout.LayoutParams layoutParams1 = new ConstraintLayout.LayoutParams(rating1, ConstraintLayout.LayoutParams.MATCH_PARENT); | |
layoutParams1.setMargins(0, 5, 0, 5); | |
llPercentage1.setBackgroundColor(Color.parseColor("#ff6f31")); | |
llPercentage1.setLayoutParams(layoutParams1); | |
//RATING STAR 2 | |
double star2 = (double) totalRateStar2; | |
double sum2 = (star2 / votersInDouble); | |
int rating2 = (int) (sum2 * widthView); | |
ConstraintLayout.LayoutParams layoutParams2 = new ConstraintLayout.LayoutParams(rating2, ConstraintLayout.LayoutParams.MATCH_PARENT); | |
layoutParams2.setMargins(0, 5, 0, 5); | |
llPercentage2.setBackgroundColor(Color.parseColor("#ff9f02")); | |
llPercentage2.setLayoutParams(layoutParams2); | |
//RATING STAR 3 | |
double star3 = (double) totalRateStar3; | |
double sum3 = (star3 / votersInDouble); | |
int rating3 = (int) (sum3 * widthView); | |
ConstraintLayout.LayoutParams layoutParams3 = new ConstraintLayout.LayoutParams(rating3, ConstraintLayout.LayoutParams.MATCH_PARENT); | |
layoutParams3.setMargins(0, 5, 0, 5); | |
llPercentage3.setBackgroundColor(Color.parseColor("#ffcf02")); | |
llPercentage3.setLayoutParams(layoutParams3); | |
//RATING STAR 4 | |
double star4 = (double) totalRateStar4; | |
double sum4 = (star4 / votersInDouble); | |
int rating4 = (int) (sum4 * widthView); | |
ConstraintLayout.LayoutParams layoutParams4 = new ConstraintLayout.LayoutParams(rating4, ConstraintLayout.LayoutParams.MATCH_PARENT); | |
layoutParams4.setMargins(0, 5, 0, 5); | |
llPercentage4.setBackgroundColor(Color.parseColor("#9ace6a")); | |
llPercentage4.setLayoutParams(layoutParams4); | |
//RATING STAR 5 | |
double star5 = (double) totalRateStar5; | |
double sum5 = (star5 / votersInDouble); | |
int rating5 = (int) (sum5 * widthView); | |
ConstraintLayout.LayoutParams layoutParams5 = new ConstraintLayout.LayoutParams(rating5, ConstraintLayout.LayoutParams.MATCH_PARENT); | |
layoutParams5.setMargins(0, 5, 0, 5); | |
llPercentage5.setBackgroundColor(Color.parseColor("#57bb8a")); | |
llPercentage5.setLayoutParams(layoutParams5); | |
// menampilkan rating berdasarkan angka | |
int totalBintangSatu = totalRateStar1 * 1; | |
int totalBintangDua = totalRateStar2 * 2; | |
int totalBintangTiga = totalRateStar3 * 3; | |
int totalBintangEmpat = totalRateStar4 * 5; | |
int totalBintangLima = totalRateStar5 * 5; | |
double sumBintang = totalBintangSatu + | |
totalBintangDua + | |
totalBintangTiga + | |
totalBintangEmpat + | |
totalBintangLima; | |
double rating = (sumBintang / votersInDouble); | |
DecimalFormat format = new DecimalFormat(".#"); | |
tvTotalNumberRating.setText(String.valueOf(format.format(rating))); | |
totalStarRating.setRating(Float.parseFloat(String.valueOf(rating))); | |
tvTotalPemberiBintang.setText(String.valueOf(totalAllVoters) + " total"); | |
} | |
/** | |
* this method used to open dialog input review | |
*/ | |
private void openDialogReview() { | |
final Dialog dialog = new Dialog(this); | |
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT)); | |
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); | |
dialog.setContentView(R.layout.dialog_review); | |
EditText etReview = dialog.findViewById(R.id.et_review); | |
EditText etName = dialog.findViewById(R.id.et_name); | |
MaterialRatingBar rate = dialog.findViewById(R.id.rate_star); | |
Button btnKirimUlasan = dialog.findViewById(R.id.btn_send_review); | |
btnKirimUlasan.setOnClickListener(v -> { | |
dialog.dismiss(); | |
if (TextUtils.isEmpty(etReview.getText().toString())) { | |
etReview.setError("Required field"); | |
} else { | |
progressDialog.setMessage("Please wait ..."); | |
progressDialog.show(); | |
ReviewModel reviewModel = new ReviewModel(); | |
reviewModel.setName(etName.getText().toString()); | |
reviewModel.setReview(etReview.getText().toString()); | |
reviewModel.setTimeStamp(new Date()); | |
reviewModel.setTotalStarGiven(Math.round(rate.getRating())); | |
insertDataReview(reviewModel); | |
} | |
}); | |
dialog.show(); | |
} | |
/** | |
* the method used to get all reviews in firebase firestore | |
* @param idProduct | |
*/ | |
private void getAllReview(String idProduct) { | |
progressBar.setVisibility(View.VISIBLE); | |
rvReview.setVisibility(View.GONE); | |
CollectionReference collectionReference = firebaseFirestore.collection("product"); | |
DocumentReference documentReference = collectionReference.document(idProduct); | |
documentReference.collection("review") | |
.get() | |
.addOnCompleteListener(task -> { | |
progressBar.setVisibility(View.GONE); | |
rvReview.setVisibility(View.VISIBLE); | |
if (task.getResult().isEmpty()) { | |
} else if (task.isSuccessful()) { | |
List<ReviewModel> listReview = new ArrayList<>(); | |
for (DocumentSnapshot documentSnapshot : task.getResult()) { | |
ReviewModel reviewModel = new ReviewModel(); | |
try { | |
reviewModel.setName(documentSnapshot.get("name").toString()); | |
reviewModel.setReview(documentSnapshot.get("review").toString()); | |
reviewModel.setTimeStamp(new Date(documentSnapshot.get("timeStamp").toString())); | |
reviewModel.setTotalStarGiven(Double.parseDouble(documentSnapshot.get("totalStarGiven").toString())); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
listReview.add(reviewModel); | |
initListReview(listReview); | |
} | |
} | |
}) | |
.addOnFailureListener(new OnFailureListener() { | |
@Override | |
public void onFailure(@NonNull Exception e) { | |
} | |
}); | |
} | |
//this method used to populating the recyclerview with data of reviews | |
private void initListReview(List<ReviewModel> reviewModels) { | |
adapter = new ReviewAdapter(reviewModels); | |
rvReview.setLayoutManager(new LinearLayoutManager(this)); | |
rvReview.setAdapter(adapter); | |
} | |
@Override | |
public boolean onCreateOptionsMenu(Menu menu) { | |
MenuInflater menuInflater = getMenuInflater(); | |
menuInflater.inflate(R.menu.main_menu, menu); | |
return super.onCreateOptionsMenu(menu); | |
} | |
@Override | |
public boolean onOptionsItemSelected(MenuItem item) { | |
int id = item.getItemId(); | |
if (id == R.id.action_add_review) { | |
openDialogReview(); | |
} | |
return super.onOptionsItemSelected(item); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<uses-permission android:name="android.permission.INTERNET"/> |
Download the project : LINK GITHUB
4 komentar
when i copy all code in tpo my app it give error and run failed
TextView tvTglRating show null
I executed successfully . I tried to import in my current project application.. I copy all the codes accordingly. But there is one small problem i cannot fix.
Inside the ReviewActivity, in RecyclerView (rv_review), the date and rating is showing a null value.. can you please help me???
EmoticonEmoticon