Implement Comment on a Particular Blog Functionality in Social Media Android App

This is the Part 11 of “Build a Social Media App on Android Studio” tutorial, and we are going to cover the following functionalities in this article:
- We are going to comment on the blog.
 - Here we are going to write a comment, and then we will be showing the comments and will be updating the comment count.
 - The comment feature is the best feature in any blogging app. It helps in interacting with the user who has written the blog and much more.
 
Step By Step Implementation
Step 1: Create a new layout resource file
Go to the app > res > layout > Right-click > New > Layout Resource File and name the file as row_comments. Below is the code for the row_comments.xml file.
XML
<?xml version="1.0" encoding="utf-8"?><androidx.cardview.widget.CardView     android:layout_width="match_parent"    android:layout_height="wrap_content"    android:layout_margin="1dp"    android:orientation="vertical"    app:cardBackgroundColor="@color/colorWhite"    app:contentPadding="2dp">      <RelativeLayout        android:layout_width="match_parent"        android:layout_height="wrap_content">          <de.hdodenhof.circleimageview.CircleImageView            android:id="@+id/loadcomment"            android:layout_width="40dp"            android:layout_height="40dp"            android:layout_marginEnd="5dp"            android:layout_marginRight="5dp"            android:src="@drawable/profile_image" />          <TextView            android:id="@+id/commentname"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_toRightOf="@id/loadcomment"            android:text="Anni"            android:textColor="@color/colorBlack"            android:textSize="16sp"            android:textStyle="bold" />          <TextView            android:id="@+id/commenttext"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_below="@id/commentname"            android:layout_toEndOf="@id/loadcomment"            android:layout_toRightOf="@id/loadcomment"            android:text="Actual Comment"            android:textColor="@color/colorBlack" />          <TextView            android:id="@+id/commenttime"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_below="@id/commenttext"            android:layout_toEndOf="@id/loadcomment"            android:layout_toRightOf="@id/loadcomment"            android:text="12/06/19" />    </RelativeLayout>      </androidx.cardview.widget.CardView> | 
Step 2: Create a new java class and name the class as ModelComment
Working with the ModelComment.java file. Created this activity to initialize the key so that we can retrieve the value of the key later. Below is the code for the ModelComment.java file.
Java
package com.example.socialmediaapp;  public class ModelComment {          String cId;          String comment;      String ptime;      String udp;      public String getcId() {        return cId;    }      public void setcId(String cId) {        this.cId = cId;    }      public String getComment() {        return comment;    }      public void setComment(String comment) {        this.comment = comment;    }      public String getPtime() {        return ptime;    }      public void setPtime(String ptime) {        this.ptime = ptime;    }      public String getUdp() {        return udp;    }      public void setUdp(String udp) {        this.udp = udp;    }      public String getUemail() {        return uemail;    }      public void setUemail(String uemail) {        this.uemail = uemail;    }      public String getUid() {        return uid;    }      public void setUid(String uid) {        this.uid = uid;    }      public String getUname() {        return uname;    }      public void setUname(String uname) {        this.uname = uname;    }      String uemail;      public ModelComment() {    }      String uid;      public ModelComment(String cId, String comment, String ptime, String udp, String uemail, String uid, String uname) {        this.cId = cId;        this.comment = comment;        this.ptime = ptime;        this.udp = udp;        this.uemail = uemail;        this.uid = uid;        this.uname = uname;    }      String uname;} | 
Step 3: Create another new java class and name the class as AdapterComment
Working with the AdapterComment.java file. Below is the code for the AdapterComment.java file.
Java
package com.example.socialmediaapp;  import android.content.Context;import android.text.format.DateFormat;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;  import androidx.annotation.NonNull;import androidx.recyclerview.widget.RecyclerView;  import com.bumptech.glide.Glide;  import java.util.Calendar;import java.util.List;import java.util.Locale;  public class AdapterComment extends RecyclerView.Adapter<com.example.socialmediaapp.AdapterComment.MyHolder> {      Context context;    List<ModelComment> list;      public AdapterComment(Context context, List<ModelComment> list, String myuid, String postid) {        this.context = context;        this.list = list;        this.myuid = myuid;        this.postid = postid;    }      String myuid;    String postid;        @NonNull    @Override    public MyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {        View view = LayoutInflater.from(context).inflate(R.layout.row_comments, parent, false);        return new MyHolder(view);    }      @Override    public void onBindViewHolder(@NonNull MyHolder holder, int position) {        final String uid = list.get(position).getUid();        String name = list.get(position).getUname();        String email = list.get(position).getUemail();        String image = list.get(position).getUdp();        final String cid = list.get(position).getcId();        String comment = list.get(position).getComment();        String timestamp = list.get(position).getPtime();        Calendar calendar = Calendar.getInstance(Locale.ENGLISH);        calendar.setTimeInMillis(Long.parseLong(timestamp));        String timedate = DateFormat.format("dd/MM/yyyy hh:mm aa", calendar).toString();          holder.name.setText(name);        holder.time.setText(timedate);        holder.comment.setText(comment);        try {            Glide.with(context).load(image).into(holder.imagea);        } catch (Exception e) {          }    }          @Override    public int getItemCount() {        return list.size();    }      class MyHolder extends RecyclerView.ViewHolder {          ImageView imagea;        TextView name, comment, time;          public MyHolder(@NonNull View itemView) {            super(itemView);            imagea = itemView.findViewById(R.id.loadcomment);            name = itemView.findViewById(R.id.commentname);            comment = itemView.findViewById(R.id.commenttext);            time = itemView.findViewById(R.id.commenttime);        }    }} | 
Step 4: Working with the PostDetailsActivity Activity
Working with the activity_postdetails.xml file.
XML
<?xml version="1.0" encoding="utf-8"?><RelativeLayout     android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".PostDetailsActivity">      <androidx.core.widget.NestedScrollView        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_above="@id/commentsa">          <LinearLayout            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:orientation="vertical">              <androidx.cardview.widget.CardView                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:orientation="vertical"                app:cardBackgroundColor="@color/colorWhite"                app:cardCornerRadius="3dp"                app:cardElevation="3dp"                app:cardUseCompatPadding="true"                app:contentPadding="5dp">                  <LinearLayout                    android:layout_width="match_parent"                    android:layout_height="wrap_content"                    android:orientation="vertical">                      <LinearLayout                        android:id="@+id/profilelayoutco"                        android:layout_width="match_parent"                        android:layout_height="wrap_content"                        android:gravity="center_vertical"                        android:orientation="horizontal">                          <de.hdodenhof.circleimageview.CircleImageView                            android:id="@+id/pictureco"                            android:layout_width="50dp"                            android:layout_height="50dp"                            android:scaleType="centerCrop"                            android:src="@drawable/profile_image" />                          <LinearLayout                            android:layout_width="0dp"                            android:layout_height="wrap_content"                            android:layout_weight="1"                            android:orientation="vertical">                              <TextView                                android:id="@+id/unameco"                                android:layout_width="wrap_content"                                android:layout_height="wrap_content"                                android:text="Name"                                android:textColor="@color/colorBlack"                                android:textSize="20sp" />                              <TextView                                android:id="@+id/utimeco"                                android:layout_width="wrap_content"                                android:layout_height="wrap_content"                                android:text="33 min" />                                                      </LinearLayout>                          <ImageButton                            android:id="@+id/morebtn"                            android:layout_width="wrap_content"                            android:layout_height="wrap_content"                            android:background="@null"                            android:src="@drawable/ic_more" />                      </LinearLayout>                      <TextView                        android:id="@+id/ptitleco"                        android:layout_width="match_parent"                        android:layout_height="wrap_content"                        android:text="Title"                        android:textSize="16sp"                        android:textStyle="bold" />                      <TextView                        android:id="@+id/descriptco"                        android:layout_width="match_parent"                        android:layout_height="wrap_content"                        android:text="Description"                        android:textColor="@color/colorBlack" />                      <ImageView                        android:id="@+id/pimagetvco"                        android:layout_width="match_parent"                        android:layout_height="200dp"                        android:background="@color/colorWhite" />                      <LinearLayout                        android:layout_width="match_parent"                        android:layout_height="wrap_content"                        android:orientation="horizontal">                            <TextView                            android:id="@+id/plikebco"                            android:layout_width="match_parent"                            android:layout_height="wrap_content"                            android:layout_weight="1"                            android:text="1.2K Likes"                            android:textColor="@color/colorPrimary" />                          <TextView                            android:id="@+id/pcommenttv"                            android:layout_width="match_parent"                            android:layout_height="wrap_content"                            android:layout_weight="1"                            android:text="1.2K Comment"                            android:textAlignment="textEnd"                            android:textColor="@color/colorPrimary" />                    </LinearLayout>                      <View                        android:layout_width="match_parent"                        android:layout_height="1dp"                        android:background="#F5F0F0" />                      <LinearLayout                        android:layout_width="match_parent"                        android:layout_height="wrap_content"                        android:gravity="center"                        android:orientation="horizontal">                          <Button                            android:id="@+id/like"                            android:layout_width="wrap_content"                            android:layout_height="wrap_content"                            android:layout_weight="1"                            android:autoLink="all"                            android:background="@color/colorWhite"                            android:drawableStart="@drawable/ic_like"                            android:drawableLeft="@drawable/ic_like"                            android:padding="5dp"                            android:text="Like" />                          <Button                            android:id="@+id/share"                            android:layout_width="wrap_content"                            android:layout_height="wrap_content"                            android:layout_weight="1"                            android:background="@color/colorWhite"                            android:drawableStart="@drawable/ic_share"                            android:drawableLeft="@drawable/ic_share"                            android:padding="5dp"                            android:text="SHARE" />                    </LinearLayout>                  </LinearLayout>              </androidx.cardview.widget.CardView>              <TextView                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:drawableStart="@drawable/ic_commenting"                android:drawableLeft="@drawable/ic_commenting"                android:drawablePadding="5dp"                android:padding="2dp"                android:text="Comments"                android:textColor="@color/colorBlack" />              <androidx.recyclerview.widget.RecyclerView                android:id="@+id/recyclecomment"                android:layout_width="match_parent"                android:layout_height="wrap_content" />        </LinearLayout>              </androidx.core.widget.NestedScrollView>      <RelativeLayout        android:id="@+id/commentsa"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true">          <de.hdodenhof.circleimageview.CircleImageView            android:id="@+id/commentimge"            android:layout_width="50dp"            android:layout_height="50dp"            android:src="@drawable/profile_image" />          <EditText            android:id="@+id/typecommet"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_toStartOf="@id/sendcomment"            android:layout_toEndOf="@id/commentimge"            android:layout_weight="1"            android:background="@color/colorWhite"            android:hint="Enter Comment..."            android:inputType="textCapSentences|textMultiLine"            android:padding="15dp" />          <ImageButton            android:id="@+id/sendcomment"            android:layout_width="40dp"            android:layout_height="40dp"            android:layout_alignParentRight="true"            android:background="@color/colorWhite"            android:src="@drawable/send_message" />      </RelativeLayout>      </RelativeLayout> | 
Working with the PostDetailsActivity.java file
Post Comment Using this:
DatabaseReference datarf= FirebaseDatabase.getInstance().getReference("Posts").child(postId).child("Comments");
        HashMap<String ,Object> hashMap=new HashMap<>();
        hashMap.put("cId",timestamp);
        hashMap.put("comment",commentss);
        hashMap.put("ptime",timestamp);
        hashMap.put("uid",myuid);
        hashMap.put("uemail",myemail);
        hashMap.put("udp",mydp);
        hashMap.put("uname",myname);
        datarf.child(timestamp).setValue(hashMap);
Showing Comment like this:
DatabaseReference reference= FirebaseDatabase.getInstance().getReference("Posts").child(postId).child("Comments");
        reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                commentList.clear();
                for (DataSnapshot dataSnapshot1:dataSnapshot.getChildren()){
              
                }
            }
            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
            }
        });
Below is the code for the PostDetailsActivity.java file.
Java
package com.example.socialmediaapp;  import android.app.ProgressDialog;import android.content.Intent;import android.os.Bundle;import android.text.TextUtils;import android.text.format.DateFormat;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.ImageButton;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.TextView;import android.widget.Toast;  import androidx.annotation.NonNull;import androidx.appcompat.app.ActionBar;import androidx.appcompat.app.AppCompatActivity;import androidx.recyclerview.widget.LinearLayoutManager;import androidx.recyclerview.widget.RecyclerView;  import com.bumptech.glide.Glide;import com.google.android.gms.tasks.OnFailureListener;import com.google.android.gms.tasks.OnSuccessListener;import com.google.firebase.auth.FirebaseAuth;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.Query;import com.google.firebase.database.ValueEventListener;  import java.util.ArrayList;import java.util.Calendar;import java.util.HashMap;import java.util.List;import java.util.Locale;  public class PostDetailsActivity extends AppCompatActivity {        String hisuid, ptime, myuid, myname, myemail, mydp, uimage, postId, plike, hisdp, hisname;    ImageView picture, image;    TextView name, time, title, description, like, tcomment;    ImageButton more;    Button likebtn, share;    LinearLayout profile;    EditText comment;    ImageButton sendb;    RecyclerView recyclerView;    List<ModelComment> commentList;    AdapterComment adapterComment;    ImageView imagep;    boolean mlike = false;    ActionBar actionBar;    ProgressDialog progressDialog;      @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_post_details);        actionBar = getSupportActionBar();        actionBar.setTitle("Post Details");        actionBar.setDisplayHomeAsUpEnabled(true);        actionBar.setDisplayShowHomeEnabled(true);        postId = getIntent().getStringExtra("pid");        recyclerView = findViewById(R.id.recyclecomment);        picture = findViewById(R.id.pictureco);        image = findViewById(R.id.pimagetvco);        name = findViewById(R.id.unameco);        time = findViewById(R.id.utimeco);        more = findViewById(R.id.morebtn);        title = findViewById(R.id.ptitleco);        myemail = FirebaseAuth.getInstance().getCurrentUser().getEmail();        myuid = FirebaseAuth.getInstance().getCurrentUser().getUid();        description = findViewById(R.id.descriptco);        tcomment = findViewById(R.id.pcommenttv);        like = findViewById(R.id.plikebco);        likebtn = findViewById(R.id.like);        comment = findViewById(R.id.typecommet);        sendb = findViewById(R.id.sendcomment);        imagep = findViewById(R.id.commentimge);        share = findViewById(R.id.share);        profile = findViewById(R.id.profilelayout);        progressDialog = new ProgressDialog(this);        loadPostInfo();          loadUserInfo();        setLikes();        actionBar.setSubtitle("SignedInAs:" + myemail);        loadComments();        sendb.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                postComment();            }        });        likebtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                likepost();            }        });        like.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent = new Intent(PostDetailsActivity.this, PostLikedByActivity.class);                intent.putExtra("pid", postId);                startActivity(intent);            }        });    }      private void loadComments() {          LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());        recyclerView.setLayoutManager(layoutManager);        commentList = new ArrayList<>();        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Posts").child(postId).child("Comments");        reference.addValueEventListener(new ValueEventListener() {            @Override            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {                commentList.clear();                for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {                    ModelComment modelComment = dataSnapshot1.getValue(ModelComment.class);                    commentList.add(modelComment);                    adapterComment = new AdapterComment(getApplicationContext(), commentList, myuid, postId);                    recyclerView.setAdapter(adapterComment);                }            }              @Override            public void onCancelled(@NonNull DatabaseError databaseError) {              }        });    }          private void setLikes() {        final DatabaseReference liekeref = FirebaseDatabase.getInstance().getReference().child("Likes");        liekeref.addValueEventListener(new ValueEventListener() {            @Override            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {                  if (dataSnapshot.child(postId).hasChild(myuid)) {                    likebtn.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_liked, 0, 0, 0);                    likebtn.setText("Liked");                } else {                    likebtn.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_like, 0, 0, 0);                    likebtn.setText("Like");                }            }              @Override            public void onCancelled(@NonNull DatabaseError databaseError) {              }        });    }      private void likepost() {          mlike = true;        final DatabaseReference liekeref = FirebaseDatabase.getInstance().getReference().child("Likes");        final DatabaseReference postref = FirebaseDatabase.getInstance().getReference().child("Posts");        liekeref.addValueEventListener(new ValueEventListener() {            @Override            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {                  if (mlike) {                    if (dataSnapshot.child(postId).hasChild(myuid)) {                        postref.child(postId).child("plike").setValue("" + (Integer.parseInt(plike) - 1));                        liekeref.child(postId).child(myuid).removeValue();                        mlike = false;                      } else {                        postref.child(postId).child("plike").setValue("" + (Integer.parseInt(plike) + 1));                        liekeref.child(postId).child(myuid).setValue("Liked");                        mlike = false;                    }                }            }              @Override            public void onCancelled(@NonNull DatabaseError databaseError) {              }        });    }      private void postComment() {        progressDialog.setMessage("Adding Comment");          final String commentss = comment.getText().toString().trim();        if (TextUtils.isEmpty(commentss)) {            Toast.makeText(PostDetailsActivity.this, "Empty comment", Toast.LENGTH_LONG).show();            return;        }        progressDialog.show();        String timestamp = String.valueOf(System.currentTimeMillis());        DatabaseReference datarf = FirebaseDatabase.getInstance().getReference("Posts").child(postId).child("Comments");        HashMap<String, Object> hashMap = new HashMap<>();        hashMap.put("cId", timestamp);        hashMap.put("comment", commentss);        hashMap.put("ptime", timestamp);        hashMap.put("uid", myuid);        hashMap.put("uemail", myemail);        hashMap.put("udp", mydp);        hashMap.put("uname", myname);        datarf.child(timestamp).setValue(hashMap).addOnSuccessListener(new OnSuccessListener<Void>() {            @Override            public void onSuccess(Void aVoid) {                progressDialog.dismiss();                Toast.makeText(PostDetailsActivity.this, "Added", Toast.LENGTH_LONG).show();                comment.setText("");                updatecommetcount();            }        }).addOnFailureListener(new OnFailureListener() {            @Override            public void onFailure(@NonNull Exception e) {                progressDialog.dismiss();                Toast.makeText(PostDetailsActivity.this, "Failed", Toast.LENGTH_LONG).show();            }        });    }      boolean count = false;      private void updatecommetcount() {        count = true;        final DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Posts").child(postId);        reference.addListenerForSingleValueEvent(new ValueEventListener() {            @Override            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {                if (count) {                    String comments = "" + dataSnapshot.child("pcomments").getValue();                    int newcomment = Integer.parseInt(comments) + 1;                    reference.child("pcomments").setValue("" + newcomment);                    count = false;                  }            }              @Override            public void onCancelled(@NonNull DatabaseError databaseError) {              }        });    }      private void loadUserInfo() {          Query myref = FirebaseDatabase.getInstance().getReference("Users");        myref.orderByChild("uid").equalTo(myuid).addListenerForSingleValueEvent(new ValueEventListener() {            @Override            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {                for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {                    myname = dataSnapshot1.child("name").getValue().toString();                    mydp = dataSnapshot1.child("image").getValue().toString();                    try {                        Glide.with(PostDetailsActivity.this).load(mydp).into(imagep);                    } catch (Exception e) {                      }                }            }              @Override            public void onCancelled(@NonNull DatabaseError databaseError) {              }        });    }      private void loadPostInfo() {          DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("Posts");        Query query = databaseReference.orderByChild("ptime").equalTo(postId);        query.addValueEventListener(new ValueEventListener() {            @Override            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {                  for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {                    String ptitle = dataSnapshot1.child("title").getValue().toString();                    String descriptions = dataSnapshot1.child("description").getValue().toString();                    uimage = dataSnapshot1.child("uimage").getValue().toString();                    hisdp = dataSnapshot1.child("udp").getValue().toString();                    // hisuid = dataSnapshot1.child("uid").getValue().toString();                    String uemail = dataSnapshot1.child("uemail").getValue().toString();                    hisname = dataSnapshot1.child("uname").getValue().toString();                    ptime = dataSnapshot1.child("ptime").getValue().toString();                    plike = dataSnapshot1.child("plike").getValue().toString();                    String commentcount = dataSnapshot1.child("pcomments").getValue().toString();                    Calendar calendar = Calendar.getInstance(Locale.ENGLISH);                    calendar.setTimeInMillis(Long.parseLong(ptime));                    String timedate = DateFormat.format("dd/MM/yyyy hh:mm aa", calendar).toString();                    name.setText(hisname);                    title.setText(ptitle);                    description.setText(descriptions);                    like.setText(plike + " Likes");                    time.setText(timedate);                    tcomment.setText(commentcount + " Comments");                    if (uimage.equals("noImage")) {                        image.setVisibility(View.GONE);                    } else {                        image.setVisibility(View.VISIBLE);                        try {                            Glide.with(PostDetailsActivity.this).load(uimage).into(image);                        } catch (Exception e) {                          }                    }                    try {                        Glide.with(PostDetailsActivity.this).load(hisdp).into(picture);                    } catch (Exception e) {                      }                    }            }              @Override            public void onCancelled(@NonNull DatabaseError databaseError) {              }        });    }      @Override    public boolean onSupportNavigateUp() {        onBackPressed();        return super.onSupportNavigateUp();    }      } | 
Output:
For all the drawable file used in this article please refer to this link: https://drive.google.com/drive/folders/1M_knOH_ugCuwSP5nkYzeD4dRp-Honzbe?usp=sharing
Below is the file structure after performing these operations:
				
					



