my code
**I have a UserAdapter, and a Search Fragment and the user_item and user class. The problem is, the three Click Listeners to open the "Search Fragment " the app crashe!! and close.
i hope so i give u good explanation for the problem
and thanks for the help in advance
**
public class SearchFragment extends Fragment {
private RecyclerView recyclerView;
private UserAdapter userAdapter;
private List<User> userList;
EditText search_bar;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_search, container, false);
recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
search_bar = view.findViewById(R.id.search_bar);
userList = new ArrayList<>();
userAdapter = new UserAdapter(getContext(), userList, true);
recyclerView.setAdapter(userAdapter);
readUsers();
search_bar.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
searchUsers(charSequence.toString().toLowerCase());
}
#Override
public void afterTextChanged(Editable editable) {
}
});
return view;
}
private void searchUsers(String s){
Query query = FirebaseDatabase.getInstance().getReference("Users").orderByChild("username")
.startAt(s)
.endAt(s+"\uf8ff");
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
userList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
User user = snapshot.getValue(User.class);
userList.add(user);
}
userAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void readUsers() {
final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (search_bar.getText().toString().equals("")) {
userList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
User user = snapshot.getValue(User.class);
userList.add(user);
}
userAdapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
** my code class Use**
public class User {
private String id;
private String username;
private String fullname;
private String imageurl;
private String bio;
public User(String id, String username, String fullname, String imageurl, String bio) {
this.id = id;
this.username = username;
this.fullname = fullname;
this.imageurl = imageurl;
this.bio = bio;
}
public User() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getFullname() {
return fullname;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public String getImageurl() {
return imageurl;
}
public void setImageurl(String imageurl) {
this.imageurl = imageurl;
}
public String getBio() {
return bio;
}
public void setBio(String bio) {
this.bio = bio;
}
}
my code UserAdapter
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ImageViewHolder> {
private Context mContext;
private List<User> mUsers;
private boolean isFragment;
private FirebaseUser firebaseUser;
public UserAdapter(Context context, List<User> users, boolean isFragment){
mContext = context;
mUsers = users;
this.isFragment = isFragment;
}
#NonNull
#Override
public UserAdapter.ImageViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.user_item, parent, false);
return new UserAdapter.ImageViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final UserAdapter.ImageViewHolder holder, final int position) {
firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
final User user = mUsers.get(position);
holder.btn_follow.setVisibility(View.VISIBLE);
isFollowing(user.getId(), holder.btn_follow);
holder.username.setText(user.getUsername());
holder.fullname.setText(user.getFullname());
Glide.with(mContext).load(user.getImageurl()).into(holder.image_profile);
if (user.getId().equals(firebaseUser.getUid())){
holder.btn_follow.setVisibility(View.GONE);
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (isFragment) {
SharedPreferences.Editor editor = mContext.getSharedPreferences("PREFS", MODE_PRIVATE).edit();
editor.putString("profileid", user.getId());
editor.apply();
((FragmentActivity) mContext).getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new ProfileFragment()).commit();
} else {
Intent intent = new Intent(mContext, Main2Activity.class);
intent.putExtra("publisherid", user.getId());
mContext.startActivity(intent);
}
}
});
holder.btn_follow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (holder.btn_follow.getText().toString().equals("follow")) {
FirebaseDatabase.getInstance().getReference().child("Follow").child(firebaseUser.getUid())
.child("following").child(user.getId()).setValue(true);
FirebaseDatabase.getInstance().getReference().child("Follow").child(user.getId())
.child("followers").child(firebaseUser.getUid()).setValue(true);
addNotification(user.getId());
} else {
FirebaseDatabase.getInstance().getReference().child("Follow").child(firebaseUser.getUid())
.child("following").child(user.getId()).removeValue();
FirebaseDatabase.getInstance().getReference().child("Follow").child(user.getId())
.child("followers").child(firebaseUser.getUid()).removeValue();
}
}
});
}
private void addNotification(String userid){
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Notifications").child(userid);
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("userid", firebaseUser.getUid());
hashMap.put("text", "started following you");
hashMap.put("postid", "");
hashMap.put("ispost", false);
reference.push().setValue(hashMap);
}
#Override
public int getItemCount() {
return mUsers.size();
}
public class ImageViewHolder extends RecyclerView.ViewHolder {
public TextView username;
public TextView fullname;
public CircleImageView image_profile;
public Button btn_follow;
public ImageViewHolder(View itemView) {
super(itemView);
username = itemView.findViewById(R.id.username);
fullname = itemView.findViewById(R.id.fullname);
image_profile = itemView.findViewById(R.id.image_profile);
btn_follow = itemView.findViewById(R.id.btn_follow);
}
}
private void isFollowing(final String userid, final Button button){
final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference()
.child("Follow").child(firebaseUser.getUid()).child("following");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.child(userid).exists()){
button.setText("following");
} else{
button.setText("follow");
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
** user_item**
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:orientation="vertical">
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:id="#+id/image_profile"
android:src="#mipmap/ic_launcher"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="#+id/image_profile"
android:layout_marginStart="5dp"
android:orientation="vertical"
android:layout_centerVertical="true">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/username"
android:text="username"
android:maxLines="1"
android:textStyle="bold"
android:textColor="#color/colorPrimaryDark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/fullname"
android:text="full_name"
android:maxLines="1"/>
</LinearLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="30dp"
android:background="#drawable/button_background"
android:id="#+id/btn_follow"
android:textColor="#color/colorPrimary"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:visibility="gone"/>
</RelativeLayout>
stack trace
E/AndroidRuntime: FATAL EXCEPTION: main
Process: commenting, PID: 24881
java.lang.ClassCastException: androidx.appcompat.widget.AppCompatButton cannot be cast to androidx.recyclerview.widget.RecyclerView
at commenting.Fragment.SearchFragment.onCreateView(SearchFragment.java:47)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:150)
at android.os.Handler.handleCallback(Handler.java:907)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7625)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
I/Process: Sending signal. PID: 24881 SIG: 9
Fragment.SearchFragment
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragment.SearchFragment">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/bar"
android:background="?android:attr/windowBackground">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
android:id="#+id/toolbar">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_search_light"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/search_bar"
android:background="#android:color/transparent"
android:hint="search_bar"
android:layout_marginStart="10dp"
android:inputType="text"/>
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/bar"
android:id="#+id/recycler_view"/>
</RelativeLayout>
It looks like your search fragment layout doesn't have the RecyclerView component and the button on that layout has the recycler_view id which you try to use to inflate your RecyclerView. That's why you're getting this exception.
Add a RecyclerView to your layout and set its id to recycler_view so that you can grab the RV in your code.
Related
I'm trying to put my firestore data within a recyclerview in Android. The app comes up with no errors, however no data shows up.
public class Diseaselist extends AppCompatActivity {
private TextView textView;
private FirebaseFirestore mDatabaseRef;
private Query mChartsQuery;
private RecyclerView mRecycler;
private FirebaseAuth mAuth;
private FirestoreRecyclerAdapter<Upload, ProductViewHolder> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_diseaselist);
RecyclerView recyclerView = findViewById(R.id.goodmeme);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
mAuth = FirebaseAuth.getInstance();
FirebaseUser currentUser = mAuth.getCurrentUser();
String useruid = currentUser.getUid();
Query query = rootRef.collection("users").document(useruid).collection("diagnoses")
.orderBy("disease", Query.Direction.ASCENDING);
FirestoreRecyclerOptions<Upload> options = new FirestoreRecyclerOptions.Builder<Upload>()
.setQuery(query, Upload.class)
.build();
adapter = new FirestoreRecyclerAdapter<Upload, ProductViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull ProductViewHolder holder, int position, #NonNull Upload productModel) {
holder.setProductName(productModel.getDisease());
}
#NonNull
#Override
public ProductViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
android.view.View views = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_diseaselist, parent, false);
return new ProductViewHolder(views);
}
};
recyclerView.setAdapter(adapter);
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
if (adapter != null) {
adapter.stopListening();
}
}
private class ProductViewHolder extends RecyclerView.ViewHolder {
private android.view.View view;
ProductViewHolder(android.view.View itemView) {
super(itemView);
view = itemView;
}
void setProductName(final String productName) {
CardView cview =view.findViewById(R.id.cardview);
textView = view.findViewById(R.id.texty);
textView.setText(productName);
cview.setOnClickListener(new android.view.View.OnClickListener() {
#Override
public void onClick(android.view.View view) {
Toast.makeText(getApplicationContext(), productName, Toast.LENGTH_SHORT).show();
}
});
}
}
Layout File:
<?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="match_parent"
android:padding="16dp"
tools:context=".Diseaselist"
tools:orientation="vertical">
<TextView
android:id="#+id/texty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="30sp"/>
<android.support.v7.widget.CardView
android:id="#+id/cardview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<ImageView
android:id="#+id/person_photo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginRight="16dp" />
<TextView
android:id="#+id/person_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/person_photo"
android:textSize="30sp" />
<TextView
android:id="#+id/person_age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/person_name"
android:layout_toRightOf="#+id/person_photo" />
</RelativeLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/goodmeme"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Firestore structure Firestore Structure Screenshot 2
Upload Class code:
package com.Provendor.Provendor;
import android.os.Parcel;
import android.os.Parcelable;
import java.io.Serializable;
import java.util.Calendar;
public class Upload implements Parcelable {
private String mName;
private String mImageUrl;
private String mdisease;
private String mdate;
private float mconfidence;
#Override
public int describeContents() {
return 0;
}
// write your object's data to the passed-in Parcel
#Override
public void writeToParcel(Parcel out, int flags) {
out.writeFloat(mconfidence);
out.writeString(mName);
out.writeString(mImageUrl);
out.writeString(mdisease);
out.writeString(mdate);
}
// this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
public static final Parcelable.Creator<Upload> CREATOR = new Parcelable.Creator<Upload>() {
public Upload createFromParcel(Parcel in) {
return new Upload(in);
}
public Upload[] newArray(int size) {
return new Upload[size];
}
};
// example constructor that takes a Parcel and gives you an object populated with it's values
private Upload(Parcel in) {
mconfidence = in.readInt();
mName = in.readString();
mImageUrl = in.readString();
mdisease = in.readString();
mdate = in.readString();
}
public Upload() {
mName= ""; //empty constructor needed
}
public Upload(String name, String imageUrl, String disease, float confidence) {
if (name.trim().equals("")) {
name = "No Name";
}
mdisease=disease;
mdate=java.text.DateFormat.getDateTimeInstance().format(Calendar.getInstance().getTime());
mName = name;
mImageUrl = imageUrl;
mconfidence=confidence;
}
public String getName() {
return mName;
}
public String getDisease() {
return mdisease;
}
public float getConfidence() {
return mconfidence;
}
public String getDate() {
return mdate;
}
public void setName(String name) {
mName = name;
}
public void setdate() {
mdate=java.text.DateFormat.getDateTimeInstance().format(Calendar.getInstance().getTime());
}
public void setDisease(String disease) {
mdisease = disease;
}
public void setConfidence(float confidence) {
mconfidence = confidence;
}
public String getImageUrl() {
return mImageUrl;
}
public void setImageUrl(String imageUrl) {
mImageUrl = imageUrl;
}
}
I expect the output to produce a list of diseases based on the firestore collection, however the recyclerview is left empty. When attached to debug, no errors come up! Thanks for looking this over!
You aren't getting anything from the database because the name of your fields inside the Upload class are different than the name of the fields that exist in the database. Both should match. To solve this, you either change all the name of your fields inside your Upload class to match the properties that exist in the database or your can use annotations. Because I see that you are using private fields and public getters, you should use the PropertyName annotation only in front of the getter, for instance your getName() getter should look like this:
#PropertyName("name")
public String getName() {
return mName;
}
I have a Fragment class where i want to display a list of layouts where the layout is updated with firebase data values.
This is how my data base looks (user_dubs > user_id > photo id):
Here's the fragment (UPDATED):
public class DubsFragment extends Fragment {
private static final String TAG = "DubsFragment";
//firebase
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private FirebaseDatabase mFirebaseDatabase;
private DatabaseReference myRef;
//widgets
private EditText mthisdub;
private ListView mListView;
//vars
private ArrayList<String> mDubs;
private ArrayAdapter<String> adapter;
private Context mContext;
private PostDubs mpostdubs;
private String userID;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_mydubs, container, false);
mListView = (ListView) view.findViewById(R.id.listViewz);
mDubs = new ArrayList<>();
mContext = getActivity();
mpostdubs = new PostDubs();
adapter = new ArrayAdapter<String>(mContext, R.layout.layout_dubs_listitem, R.id.getusername, mDubs);
mListView.setAdapter(adapter);
setupFirebaseAuth();
return view;
}
private void setupFirebaseAuth(){
Log.d(TAG, "setupFirebaseAuth: setting up firebase auth.");
mAuth = FirebaseAuth.getInstance();
mFirebaseDatabase = FirebaseDatabase.getInstance();
myRef = mFirebaseDatabase.getReference();
userID = mAuth.getCurrentUser().getUid();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
Query query = reference
.child(getString(R.string.dbname_userdubs))
.child(userID)
.orderByChild(getString(R.string.field_photoid));
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for ( DataSnapshot singleSnapshot : dataSnapshot.getChildren()) {
mpostdubs = singleSnapshot.getValue(PostDubs.class);
mDubs.add(mpostdubs.getEditdub().toString());
adapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
}
#Override
public void onStop() {
super.onStop();
if (mAuthListener != null) {
mAuth.removeAuthStateListener(mAuthListener);
}
}
}
Post Dubs Class:
public class PostDubs {
private String editdub;
private String dubdate;
private String user_id;
private String photoid;
private String username;
private Context mContext;
public PostDubs(String user_id, String editdub, String photoid, String dubdate, String username){
this.user_id = user_id;
this.editdub = editdub;
this.dubdate = dubdate;
this.photoid = photoid;
this.username = username;
}
public PostDubs() {
}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
public String getEditdub() {
return editdub;
}
public void setEditdub(String editdub) {
this.editdub = editdub;
}
public String getDubdate() {
return dubdate;
}
public void setDubdate(String dubdate) {
this.dubdate = dubdate;
}
public String getPhotoid() {
return photoid;
}
public void setPhotoid(String photoid) {
this.dubdate = photoid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
#Override
public String toString() {
return "User{" +
"user_id='" + editdub + '\'' +
", phone_number='" + dubdate + '\'' +
'}';
}
}
Here's the layout_dubs_listitem.xml:
<?xml version="1.0" encoding="utf-8" ?>
<RelativeLayout 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">
<RelativeLayout android:layout_width="match_parent"
android:layout_height="100dp">
<de.hdodenhof.circleimageview.CircleImageView android:layout_width="75dp"
android:layout_height="75dp"
app:civ_border_color="#color/black"
app:civ_border_width="0.5dp"
android:id="#+id/profile_image"
android:layout_marginLeft="20dp"
android:layout_centerVertical="true" />
<RelativeLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/profile_image"
android:layout_centerVertical="true">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:textSize="22sp"
android:textColor="#color/black"
android:id="#+id/editdub"
android:text=""/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:textSize="15sp"
android:layout_centerVertical="true"
android:textColor="#color/black"
android:id="#+id/getusername"
android:text=""/>
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
For the test, I'm just trying to get the edit dub in the layout but it is not working at all. I am sure I am doing something stupid.
Please guide me with this problem and it would be very helpful if you could help me update the layout with other child values like username. Thanks.
I fixed it by ordering my child in the firebase correctly.
I'm new to the concepts of RecyclerView and Firebase; I'm working on this chat app that takes input from the user (message) and takes the DisplayName(Google sign in, so the Username) and stores it to the realtime database of the Firebase. The storing of the "mAuthor" and "mMessage" is working fine, the problem arises when I'm trying to retrieve the data and display it in the recyclerView. There's no crash error as per the Logcat, however, there's nothing getting displayed on my chat app screen (in the recyclerView).
The dependencies of firebase and recyclerView have been carefully added.
Here's my activity class:
private String mDisplayName;
private EditText mMessage;
private ImageView mSendButton;
private RecyclerView mRecycler;
private DatabaseReference mDatabaseReference;
private MyAdapter mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
mMessage=(EditText) findViewById(R.id.messageInput);
mSendButton=(ImageView) findViewById(R.id.sendButton);
setupDisplayName();
mDatabaseReference= FirebaseDatabase.getInstance().getReference();
mRecycler=(RecyclerView) findViewById(R.id.chat_recycler_view);
mRecycler.setHasFixedSize(true);
LinearLayoutManager layoutManager= new LinearLayoutManager(ChatActivity.this);
mRecycler.setLayoutManager(layoutManager);
mMessage.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
sendMessage();
return true;
}
});
mSendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sendMessage();
}
});
}
private void setupDisplayName(){
Intent mIntent= getIntent();
String option= mIntent.getStringExtra("Options");
if(option.equals("normal")){
SharedPreferences prefs= getSharedPreferences(RegisterActivity.CHAT_PREFS,0);
mDisplayName=prefs.getString(RegisterActivity.DISPLAY_NAME_KEY,null);
Log.d("Google","Shared prefs: DisplayName:"+mDisplayName);
}
else if(option.equals("google")){
SharedPreferences prefs= getSharedPreferences(MainActivity.CHAT_PREFS,0);
mDisplayName=prefs.getString(MainActivity.DISPLAY_NAME_KEY,null);
Log.d("Google","Shared prefs: DisplayName:"+mDisplayName);
}
if(mDisplayName==null)
mDisplayName="Anonymous";
}
private void sendMessage() {
String input= mMessage.getText().toString();
if(!input.equals("")){
Log.d("Google","I sent something");
InstantMessage mObject= new InstantMessage(mDisplayName, input);
mDatabaseReference.child("messages").push().setValue(mObject);
mMessage.setText("");
}
}
#Override
public void onStart() {
super.onStart();
mAdapter= new MyAdapter(mDatabaseReference, mDisplayName);
mRecycler.setAdapter(mAdapter);
}
#Override
public void onStop(){
super.onStop();
mAdapter.CleanUp();
}
Here's my Model class:
public class InstantMessage {
private String mAuthor;
private String mMessage;
public InstantMessage(String mAuthor, String mMessage) {
this.mAuthor = mAuthor;
this.mMessage = mMessage;
}
public InstantMessage() {
}
public String getmAuthor() {
return mAuthor;
}
public void setmAuthor(String mAuthor) {
this.mAuthor = mAuthor;
}
public void setmMessage(String mMessage) {
this.mMessage = mMessage;
}
public String getmMessage() {
return mMessage;
}
}
Here's my Adapter class:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private DatabaseReference mReference;
private String mDisplayName;
private List<InstantMessage> mList;
private ChildEventListener mListener= new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
InstantMessage msg= dataSnapshot.getValue(InstantMessage.class);
mList.add(msg);
Log.d("Google","Datasnapshot added:"+dataSnapshot.toString());
notifyDataSetChanged();
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
};
public MyAdapter( DatabaseReference mReference, String mDisplayName) {
this.mReference = mReference.child("messages");
mReference.addChildEventListener(mListener);
this.mDisplayName = mDisplayName;
mList= new ArrayList<>();
}
#NonNull
#Override
public MyAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_chat_row, parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyAdapter.ViewHolder holder, int position) {
holder.mAuthorName.setText(mList.get(position).getmAuthor());
holder.mText.setText(mList.get(position).getmMessage());
}
#Override
public int getItemCount() {
Log.d("Google","Item count:"+mList.size());
return mList.size();
}
public void CleanUp(){
mReference.removeEventListener(mListener);
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView mAuthorName;
TextView mText;
public ViewHolder(View itemView) {
super(itemView);
mAuthorName=(TextView) itemView.findViewById(R.id.Chatauthor);
mText= (TextView) itemView.findViewById(R.id.Chatmessage);
}
}
}
I'm not sure what I'm doing wrong. In the log statement of onChildAdded method, the datasnapshot.toString() returns legit values. However, the Log.d("Google","Item Count:"+mList.size()) returns ItemCount: 1 everytime
PS: Here's the data that is being sent to the firebase: https://imageshack.com/a/img922/1458/HoOWxO.png
My activity_chat_row.xml code:
<?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"
android:orientation="vertical">
<TextView
android:id="#+id/Chatauthor"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:layout_gravity="start"
android:textColor="#3CB371"
android:gravity="center_vertical"
android:textSize="15sp"
android:textStyle="bold"
android:text="Author"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/Chatmessage"
android:layout_gravity="start"
android:gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:padding="10dp"
android:textSize="15sp"
android:text="Text"
android:textColor="#android:color/primary_text_light"
/>
</LinearLayout>
I'm building a RecyclerView in a Fragment, which brings in data from Firebase database and suppose to show them on a CardView. I wrote all the code as shown below but all that appears upon running is an empty RecyclerView Fragment with the method getItemCount() returning always 0.
card_item.xml
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/cardView"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_margin="10dp"
android:orientation="horizontal"
card_view:cardCornerRadius="5dp"
card_view:cardElevation="5dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorPrimary">
<TextView
android:id="#+id/primaryText"
android:layout_width="300dp"
android:layout_height="60dp"
android:textColor="#color/colorPrimary"
android:textSize="24sp" />
<TextView
android:id="#+id/subText"
android:layout_width="300dp"
android:layout_height="60dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:textColor="#color/colorPrimary"
android:textSize="14sp" />
<TextView
android:id="#+id/rateValue"
android:layout_width="300dp"
android:layout_height="60dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="#+id/subText"
android:textColor="#color/colorPrimary"
android:textSize="24sp" />
</RelativeLayout>
fragment_profile.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F1F1F1"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/placesRecycler"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
PlacesModel.java
public class PlaceModel {
private String mPrimaryText, mSubText, mRateValue;
public PlaceModel() {
}
public PlaceModel(String mCardImage, String mPrimaryText,
String mSubText, String mRateValue) {
//this.mCardImageURL = mCardImage;
this.mPrimaryText = mPrimaryText;
this.mSubText = mSubText;
this.mRateValue = mRateValue;
}
public void setmPrimaryText(String mPrimaryText) {
this.mPrimaryText = mPrimaryText;
}
public void setmSubText(String mSubText) {
this.mSubText = mSubText;
}
public void setmRateValue(String mRateValue) {
this.mRateValue = mRateValue;
}
public String getmPrimaryText() {
return mPrimaryText;
}
public String getmSubText() {
return mSubText;
}
public String getmRateValue() {
return mRateValue;
}}
PlacesAdapter.java
public class PlacesAdapter extends RecyclerView.Adapter<PlacesAdapter.PlacesViewHolder> {
private ArrayList<PlaceModel> cardContents;
private Context context;
public PlacesAdapter(Context context, ArrayList<PlaceModel> cardContents) {
this.cardContents = cardContents;
this.context = context;
}
#Override
public PlacesViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.card_item, parent, false);
return new PlacesViewHolder(view);
}
#Override
public void onBindViewHolder(PlacesViewHolder holder, int position) {
PlaceModel place = cardContents.get(position);
holder.primaryText.setText(place.getmPrimaryText());
holder.subText.setText(place.getmSubText());
holder.rateValue.setText(place.getmRateValue());
}
#Override
public int getItemCount() {
return cardContents.size();
}
public class PlacesViewHolder extends RecyclerView.ViewHolder {
CardView cardView;
public TextView primaryText, subText, rateValue;
public PlacesViewHolder(View itemView) {
super(itemView);
cardView = (CardView) itemView.findViewById(R.id.cardView);
primaryText = (TextView) itemView.findViewById(R.id.primaryText);
subText = (TextView) itemView.findViewById(R.id.subText);
rateValue = (TextView) itemView.findViewById(R.id.rateValue);
}
}}
FirebaseConnector.java
public class FirebaseConnector {
DatabaseReference db;
PlaceModel placeModel = new PlaceModel();
ArrayList<PlaceModel> cardContent = new ArrayList<>();
public FirebaseConnector(DatabaseReference db) {
this.db = db;
}
public ArrayList<PlaceModel> retrieve() {
db.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
return cardContent;
}
private void fetchData(DataSnapshot dataSnapshot) {
cardContent.clear(); //clear card content from last usage
for (DataSnapshot ds : dataSnapshot.getChildren()) {
placeModel = ds.child("Place Model").getValue(PlaceModel.class);
cardContent.add(placeModel);
}
}}
ProfileFragment.java
public class ProfileFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
/////////////////////////////////////////////////////////////
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private RecyclerView placesRecycler;
private PlacesAdapter placesAdapter;
private FirebaseConnector connector;
private DatabaseReference ref;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
public ProfileFragment() {
// Required empty public constructor
}
// TODO: Rename and change types and number of parameters
public static ProfileFragment newInstance(String param1, String param2) {
ProfileFragment fragment = new ProfileFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_profile, container, false);
mAuth = FirebaseAuth.getInstance();
//Initialize Database..
ref = FirebaseDatabase.getInstance().getReference();
connector = new FirebaseConnector(ref);
//Initialize RecyclerView
placesRecycler = (RecyclerView)v.findViewById(R.id.placesRecycler);
placesRecycler.setLayoutManager(new LinearLayoutManager(this.getActivity()));
//Adapter
placesAdapter = new PlacesAdapter(this.getActivity(), connector.retrieve());
placesRecycler.setAdapter(placesAdapter);
Toast.makeText(getActivity(), "We have "+placesAdapter.getItemCount()+" cards", Toast.LENGTH_LONG).show();
return v;
}
#Override
public void onStart() {
super.onStart();
if (mAuth.getCurrentUser() == null) {
startActivity(new Intent(getActivity(), LoginActivity.class));
}
}
public void updateUI() {
if (mAuth.getCurrentUser() == null) {
startActivity(new Intent(getActivity(), LoginActivity.class));
}
}}
Database trial structure
Database trial structure
I see that retrieve method will return empty array list because it won't wait for the listener to finish (note that listener works in another thread)
You may make move the listener to the profile fragment and every time you update the ArrayList write
placesRecycler.notifydatasetchanged();
My main activity shows an empty RecyclerView. My CardView is not displayed.
The data is stored in a Firebase Database but is not displayed for some reason.
I have also searched the web but nothing helped me. I tried everything listed on web as well as on Stack Overflow.
MainActivity.java
public class MainActivity1 extends AppCompatActivity {
private RecyclerView mQuestionList;
private CardView mCardVieww;
private DatabaseReference mDatabase;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private DatabaseReference mDatabaseUsers;
private LinearLayoutManager layoutManager;
private DatabaseReference mDatabaseCurrentUsers;
private DatabaseReference mDatabaseLike;
private boolean mProcessLike = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main1);
mAuth=FirebaseAuth.getInstance();
mAuthListener=new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
if (firebaseAuth.getCurrentUser()== null){
Intent loginIntent=new Intent(MainActivity1.this,LoginActivity.class);
loginIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(loginIntent);
}
}
};
mDatabase= FirebaseDatabase.getInstance().getReference().child("Question");
mDatabaseUsers=FirebaseDatabase.getInstance().getReference().child("Users");
mDatabaseLike=FirebaseDatabase.getInstance().getReference().child("Likes");
mDatabaseUsers.keepSynced(true);
mDatabaseLike.keepSynced(true);
mDatabase.keepSynced(true);
mQuestionList=(RecyclerView) findViewById(R.id.question_list);
layoutManager=new LinearLayoutManager(this);
layoutManager.setReverseLayout(true);
layoutManager.setStackFromEnd(true);
mQuestionList.setHasFixedSize(true);
mQuestionList.setLayoutManager(layoutManager);
checkUserExist();
}
#Override
protected void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
FirebaseRecyclerAdapter <Question,QuestionViewHolder> fireRecyclerAdapter = new FirebaseRecyclerAdapter <Question,QuestionViewHolder>(
Question.class,
R.layout.question,
QuestionViewHolder.class,
mDatabase
){
#Override
protected void populateViewHolder(QuestionViewHolder viewHolder,Question model, int position){
final String post_key = getRef(position).getKey()
viewHolder.setTitle(model.getTitle());
viewHolder.setDesc(model.getDesc());
viewHolder.setImage(getApplicationContext(),model.getImage());
viewHolder.setUsername(model.getUsername());
viewHolder.setLikeBtn(post_key);
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Toast.makeText(MainActivity1.this,post_key,Toast.LENGTH_LONG).show();
Intent singleQuestionIntent=new Intent(MainActivity1.this,QuestionSingleActivity.class);
singleQuestionIntent.putExtra("question_id",post_key);
startActivity(singleQuestionIntent);
}
});
viewHolder.mLikeBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mProcessLike = true;
mDatabaseLike.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (mProcessLike) {
if (dataSnapshot.child(post_key).hasChild(mAuth.getCurrentUser().getUid())) {
mDatabaseLike.child(post_key).child(mAuth.getCurrentUser().getUid()).removeValue();
mProcessLike = false;
} else {
mDatabaseLike.child(post_key).child(mAuth.getCurrentUser().getUid()).setValue("RandomValue");
mProcessLike = false;
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
}
};
mQuestionList.setHasFixedSize(true);
mQuestionList.setLayoutManager(layoutManager);
mQuestionList.setAdapter(fireRecyclerAdapter);
}
//cgeck user exist or not
private void checkUserExist() {
if (mAuth.getCurrentUser() != null) {
final String user_id = mAuth.getCurrentUser().getUid();
mDatabaseUsers.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (!dataSnapshot.hasChild(user_id)) {
Intent setupIntent = new Intent(MainActivity1.this, SetupActivity.class);
setupIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(setupIntent);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
public static class QuestionViewHolder extends RecyclerView.ViewHolder{
View mView;
ImageButton mLikeBtn;
DatabaseReference mDatabaseLike;
FirebaseAuth mAuth;
public QuestionViewHolder(View itemView) {
super(itemView);
mView=itemView;
mLikeBtn=(ImageButton) mView.findViewById(R.id.likeBtn);
mDatabaseLike= FirebaseDatabase.getInstance().getReference().child("Likes");
mAuth=FirebaseAuth.getInstance();
mDatabaseLike.keepSynced(true);
}
public void setLikeBtn(final String post_key){
mDatabaseLike.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.child(post_key).hasChild(mAuth.getCurrentUser().getUid())){
mLikeBtn.setImageResource(R.mipmap.thumb_grey);
}else{
mLikeBtn.setImageResource(R.mipmap.thumb_grey);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
public void setTitle(String title){
TextView post_title=(TextView) mView.findViewById(R.id.post_title);
post_title.setText(title);
}
public void setDesc(String desc){
TextView post_desc=(TextView) mView.findViewById(R.id.post_desc);
post_desc.setText(desc);
}
public void setUsername(String username){
TextView post_username=(TextView) mView.findViewById(R.id.post_username);
post_username.setText(username);
}
public void setImage(final Context ctx, final String image){
final ImageView post_image=(ImageView) mView.findViewById(R.id.post_image);
//Picasso.with(ctx).load(image).into(post_image);
Picasso.with(ctx).load(image).networkPolicy(NetworkPolicy.OFFLINE).into(post_image, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Picasso.with(ctx).load(image).into(post_image);
}
});
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu,menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId()==R.id.action_add){
startActivity(new Intent(MainActivity1.this,PostActivity.class));
}
if(item.getItemId()==R.id.action_logout){
logout();
}
if(item.getItemId()==R.id.action_Qp){
startActivity(new Intent(MainActivity1.this,MainActivity2.class));
}
return super.onOptionsItemSelected(item);
}
private void logout() {
mAuth.signOut();
}
}
Question.java
public class Question {
private CardView mCardView;
private String title;
private String desc;
private String image;
private String username;
public Question(){
}
public Question(String title, String desc, String image,String username) {
this.title = title;
this.desc = desc;
this.image = image;
this.username = username;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
activity_main1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.akhil.rtmnuforum.MainActivity1">
<android.support.v7.widget.RecyclerView
android:id="#+id/question_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
question.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
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:id="#+id/cardview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:visibility="visible"
tools:context="com.example.akhil.rtmnuforum.MainActivity1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/post_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="#mipmap/add_btn" />
<TextView
android:id="#+id/post_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="15dp"
android:text="Post Title Goes here"
android:textSize="16dp"
android:textStyle="bold" />
<TextView
android:id="#+id/post_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="15dp"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:text="Question Description Goes here" />
<TextView
android:id="#+id/post_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="15dp"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:text="username"
android:textSize="12dp"
android:textStyle="bold" />
<ImageButton
android:id="#+id/likeBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="#color/cardview_light_background"
app:srcCompat="#mipmap/ic_thumb_up_black_24dp" />
</LinearLayout>
</android.support.v7.widget.CardView>