E/RecyclerView: No adapter attached; skipping layout. No data is displayed [closed] - android

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I am trying to fetch data from firebase and put it into a recycler view through adapter. But, no data is being displayed.
My code in Main Activity:
DatabaseReference databaseReference;
RecyclerView recyclerView;
ArrayList<Menu> menuList;
EditMenuAdapter editMenuAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_menu);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
menuList = new ArrayList<Menu>();
databaseReference = FirebaseDatabase.getInstance().getReference().child("menu");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
Menu menu = dataSnapshot1.getValue(Menu.class);
menuList.add(menu);
}
editMenuAdapter = new EditMenuAdapter(EditMenuActivity.this, menuList);
recyclerView.setAdapter(editMenuAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(EditMenuActivity.this, "Something went wrong", Toast.LENGTH_LONG).show();
}
});
My adapter class:
public class EditMenuAdapter extends RecyclerView.Adapter<EditMenuAdapter.MyViewHolder> {
Context context;
ArrayList<Menu> menuArrayList;
public EditMenuAdapter(Context c, ArrayList<Menu> menus) {
context = c;
menuArrayList = menus;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.menu_list_layout, parent, false));
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.dishNameTextView.setText(menuArrayList.get(position).getDishName());
holder.dishPriceTextView.setText(menuArrayList.get(position).getDishPrice());
}
#Override
public int getItemCount() {
return menuArrayList.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView dishNameTextView;
TextView dishPriceTextView;
Switch dishActiveSwitch;
public MyViewHolder(View view) {
super(view);
dishNameTextView = (TextView) view.findViewById(R.id.dishNameTextView);
dishPriceTextView = (TextView) view.findViewById(R.id.dishPriceTextView);
dishActiveSwitch = (Switch) view.findViewById(R.id.dishActiveSwitch);
}
}
}
The layout resource file is:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".EditMenuActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="397dp"
android:layout_height="599dp"
android:layout_marginStart="20dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/doneButton"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginStart="20dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="20dp"
android:text="Done"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/recyclerView" />
The log shows: E/RecyclerView: No adapter attached; skipping layout. No data is displayed.
Only the switch is being displayed on the screen. Please help!

Create instance of adapter in onCreate and attach it to RV:
protected void onCreate(Bundle savedInstanceState) {
...
editMenuAdapter = new EditMenuAdapter(this, new ArrayList<>());
recyclerView.setAdapter(adapter);
...
}
In the response of Firebase onDataChange:
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
...
editMenuAdapter.setItems(menuList);
runOnUiThread(() -> editMenuAdapter.notifyDataSetChanged());
}

Related

firebase data recyclerview sometimes show nothing

I trying to show firebase data by using recyclerview.
retrieving data is well, I can check it in logcat.
Sometimes recyclerview show data, but Usually show nothing.
When recycleview show data, it is reflectled firebase data well.
Who can tell me What the problem?? Is there mistake in my xml code?
Java code
artistData.child(starList[i]).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot starDataSnap) {
int fanNums = (int) starDataSnap.child("fanNums").getValue(Integer.class);
int placeNums = (int) starDataSnap.child("placeNums").getValue(Integer.class);
Log.d("####", finalStarName + fanNums + placeNums);
drawerStarImage = getResources().getIdentifier(finalStarImgName, "drawable", getActivity().getPackageName());
ItemStarData itemStarData = new ItemStarData();
itemStarData.setStarImage(drawerStarImage);
itemStarData.setStarName(finalStarName);
itemStarData.setFanNums(fanNums);
itemStarData.setPlaceNums(placeNums);
drawerStarList.add(itemStarData);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
Adapter class code
public class AdapterStarlist extends RecyclerView.Adapter<AdapterStarlist.ViewHolder>{
ArrayList<ItemStarData> array;
Context context;
public AdapterStarlist(ArrayList<ItemStarData> array, Context context) {
this.array = array;
this.context =context;
}
#NonNull
#Override
public AdapterStarlist.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.item_home_starlist,parent,false);
return new AdapterStarlist.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull AdapterStarlist.ViewHolder holder, int position) {
Log.d("####", array.get(position).getStarName());
holder.Imgstarlist.setImageResource(array.get(position).getStarImage());
holder.followStarName.setText(String.valueOf(array.get(position).getStarName()));
holder.starlistfanNum.setText(String.valueOf(array.get(position).getFanNums()));
holder.starlistPlaceNum.setText(String.valueOf(array.get(position).getPlaceNums()));
}
#Override
public int getItemCount() {
return array.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView Imgstarlist;
TextView followStarName;
TextView starlistfanNum;
TextView starlistPlaceNum;
public ViewHolder(#NonNull View itemView) {
super(itemView);
Imgstarlist =itemView.findViewById(R.id.Imgstarlist);
followStarName =itemView.findViewById(R.id.followStarName);
starlistfanNum =itemView.findViewById(R.id.starlistfanNum);
starlistPlaceNum =itemView.findViewById(R.id.starlistPlaceNum);
Imgstarlist.setBackground(new ShapeDrawable(new OvalShape()));
Imgstarlist.setClipToOutline(true);
}
}
}
Part of xml code
<ScrollView
android:layout_width="match_parent"
android:layout_height="480dp"
android:layout_marginTop="24dp"
android:fillViewport="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/DrawerStarlist"
>
<RelativeLayout
android:id="#+id/rlDrawerStarlist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/DrawerStarlist">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvDrawerStarlist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
/>
</RelativeLayout>
</ScrollView>
It looks like you're adding the data to the drawerStarList list, but not telling the adapter that you've done so. Until you tell the adapter of the change (by calling notifyDataSetChanged() on it), it won't repaint the UI for the list.
So typically this would look something like:
artistData.child(starList[i]).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot starDataSnap) {
...
drawerStarList.add(itemStarData);
adapter.notifyDataSetChanged(); // tell the adapter to repaint its views
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException(); // never ignore errors
}
});
With adapter being a reference to the adapter that you use to manage drawerStarList.

android visible for linearlayout does not work

I create one recyclerview with address. When this recyclerview is empty, want one spesicif LinearLayout appear and when recyclerView has one or more items this LinearLayout disapear.But it is not working. I use funtions setVisibility(). Please help!!!
My code for xml is:
<?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:background="#color/user_location_bg_color"
android:orientation="vertical"
tools:context=".UserLocationActivity">
<ImageButton
android:id="#+id/user_location_back_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="50dp"
android:background="#color/my_account_bg_color"
android:contentDescription="#null"
android:src="#drawable/ic_back" />
<TextView
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="40dp"
android:text="#string/user_location_text"
android:textColor="#color/black"
android:textSize="20sp"
android:textStyle="bold" />
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginStart="20dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="20dp"
android:background="#color/black" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/coffee_recycler_bg_color" />
<LinearLayout
android:id="#+id/empty_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="invisible">
<pl.droidsonroids.gif.GifImageView
android:id="#+id/location_giffy"
android:layout_width="wrap_content"
android:layout_height="300dp"
android:src="#drawable/location_gif" />
<TextView
android:id="#+id/user_location_blank_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="60dp"
android:layout_marginTop="50dp"
android:layout_marginEnd="60dp"
android:gravity="center"
android:text="#string/user_address_blank_text"
android:textColor="#color/black"
android:textSize="15sp" />
</LinearLayout>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center|bottom"
android:orientation="vertical">
<Button
android:id="#+id/add_new_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="50dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="10dp"
android:backgroundTint="#color/btn_add_new_address"
android:text="#string/btn_add_new_address_text"
android:textAllCaps="false"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
My code for Activity is:
public class UserLocationActivity extends AppCompatActivity implements AddressAdapter.OnAddressListener {
//Init Variables
RecyclerView recyclerAddress;
private FirebaseDatabase db = FirebaseDatabase.getInstance();
private DatabaseReference ref = db.getReference().child("UserAddress");
private AddressAdapter adapter;
private ArrayList<UserLocation> list;
public LinearLayout empty_address;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_location);
recyclerAddress = findViewById(R.id.recycler_address);
recyclerAddress.setHasFixedSize(true);
recyclerAddress.setLayoutManager(new LinearLayoutManager(this));
list = new ArrayList<>();
adapter = new AddressAdapter(this, list, this);
recyclerAddress.setAdapter(adapter);
empty_address = findViewById(R.id.empty_address);
if (adapter.getItemCount() == 0) {
//making it semi-transparent
empty_address.setVisibility(LinearLayout.VISIBLE);
}
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
UserLocation userLocation = dataSnapshot.getValue(UserLocation.class);
list.add(userLocation);
}
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
#Override
public void onAddressItemDelete(int position) {
}
}
My adapter code is:
public class AddressAdapter extends RecyclerView.Adapter<AddressAdapter.AddressViewHolder> {
private List<UserLocation> listData = new ArrayList<>();
UserLocationActivity userLocationActivity;
private OnAddressListener mOnAddressListener;
public AddressAdapter(UserLocationActivity userLocationActivity, List<UserLocation> listData, OnAddressListener onAddressListener){
this.listData = listData;
this.userLocationActivity = userLocationActivity;
this.mOnAddressListener = onAddressListener;
}
#NonNull
#Override
public AddressViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(userLocationActivity).inflate(R.layout.address_item , parent, false);
return new AddressViewHolder(v,mOnAddressListener);
}
#Override
public void onBindViewHolder(#NonNull AddressViewHolder holder, int position) {
UserLocation userLocation = listData.get(position);
holder.addressItem.setText(userLocation.getUserLocation());
}
#Override
public int getItemCount() {
if (listData.size() == 0){
userLocationActivity.empty_address.setVisibility(LinearLayout.VISIBLE);
}
return listData.size();
}
public static class AddressViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView addressItem;
public ImageView btnAddressItemDelete;
OnAddressListener onAddressListener;
public AddressViewHolder(View itemView, OnAddressListener onAddressListener){
super(itemView);
addressItem = itemView.findViewById(R.id.address_item);
btnAddressItemDelete = itemView.findViewById(R.id.btn_address_item_delete);
this.onAddressListener = onAddressListener;
}
#Override
public void onClick(View v) {
onAddressListener.onAddressItemDelete(getAdapterPosition());
}
}
public interface OnAddressListener{
void onAddressItemDelete(int position);
}
}
It seems there's a bug in your code, I have fixed it.
The bug is you're checking recyclerView is empty first then adding the data into recyclerView
public class UserLocationActivity extends AppCompatActivity implements AddressAdapter.OnAddressListener {
//Init Variables
RecyclerView recyclerAddress;
private FirebaseDatabase db = FirebaseDatabase.getInstance();
private DatabaseReference ref = db.getReference().child("UserAddress");
private AddressAdapter adapter;
private ArrayList<UserLocation> list;
public LinearLayout empty_address;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_location);
recyclerAddress = findViewById(R.id.recycler_address);
recyclerAddress.setHasFixedSize(true);
recyclerAddress.setLayoutManager(new LinearLayoutManager(this));
list = new ArrayList<>();
adapter = new AddressAdapter(this, list, this);
recyclerAddress.setAdapter(adapter);
empty_address = findViewById(R.id.empty_address);
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
UserLocation userLocation =
dataSnapshot.getValue(UserLocation.class);
list.add(userLocation);
}
adapter.notifyDataSetChanged();
if (list.size() == 0) {
empty_address.setVisibility(View.VISIBLE);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
#Override
public void onAddressItemDelete(int position) {
}
}

print all users list in android app using firebase

I am working on printing all users based on the UID, but I only get one user printed.
This is the result I am getting now.
Here is what the printingUserList(), this is a small function to retrieve all user information based on UID.
RecyclerView rv;
UserAdapter usrAdapter;
ArrayList<User> mUsrsList;
private void readUsrs(){
LinearLayoutManager LayoutManager = new LinearLayoutManager(this);
rv.setLayoutManager(LayoutManager);
mUsrsList = new ArrayList<>();
final FirebaseUser me = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("users");
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mUsrsList.clear();
for (DataSnapshot ds: dataSnapshot.getChildren()) {
Log.d("TAG_", "A++" + dataSnapshot.getChildrenCount()); //prints 5, which exactly has five users in the database.
User all_usr = ds.getValue(User.class);
if (!all_usr.getUid().equals(me.getUid())) { //won't print itself
mUsrsList.add(all_usr);
}
}
System.out.println(mUsrsList.toString());
usrAdapter = new UserAdapter(RoomUser_Activity.this, mUsrsList);
rv.setAdapter(usrAdapter);
usrAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) { }
});
}
and this is the recyclerview, should be correct otherwise it prints nothing
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.UserViewHolder> {
private Context m_context;
private ArrayList<User> all_users;
public static final String EXTRA_HISUID = "NoHisUID";
public UserAdapter(Context context, ArrayList<User> all_users) {
this.m_context = context;
this.all_users = all_users;
}
#NonNull
#Override
public UserAdapter.UserViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(m_context);
View itemv = inflater.inflate(R.layout.layout_item_user, parent, false); //xml provide below
return new UserViewHolder(itemv);
}
public class UserViewHolder extends RecyclerView.ViewHolder{
public ImageView UserIcon; //default icon provided in xml
public TextView Username;
public UserViewHolder (View itemView){
super(itemView);
UserIcon = (ImageView)itemView.findViewById(R.id.usr_icon);
Username = (TextView)itemView.findViewById(R.id.tv_username);
}
}
public void onBindViewHolder(#NonNull UserAdapter.UserViewHolder holder, int position) {
User usr = all_users.get(position);
final String hisUID = usr.getUid();
holder.Username.setText(usr.getUsername());
if(usr.getIcon().equals("default_icon")){
holder.UserIcon.setImageResource(R.drawable.default_icon);
}
else{
Glide.with(m_context).load(usr.getIcon()).into(holder.UserIcon);
}
}
public int getItemCount() {
return all_users.size();
}
layout_item_user.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:padding="10dp"
android:layout_height="match_parent">
<ImageView
android:id="#+id/usr_icon"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="#mipmap/ic_launcher" />
<TextView
android:id="#+id/tv_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginLeft="13dp"
android:layout_toEndOf="#+id/usr_icon"
android:layout_toRightOf="#+id/usr_icon"
android:text="username"
android:textSize="18sp" />
<TextView
android:id="#+id/lastMessageTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="The last message"
android:layout_marginStart="4dp"
android:maxLines="2"
android:layout_marginTop="3dp"
android:layout_toRightOf="#id/usr_icon"
android:layout_below="#id/tv_username"
android:layout_marginLeft="13dp" />
</RelativeLayout>
database:
users:
|-2NUPkQuHFRS49ZHDZzEtWiErIiv1
|-address: "920 West 4th Ave apt231"
|-city: "blank"
|-donut: 0
|-email: "not_busy#gmail.com"
|-full_name: "blank"
|-icon: "default_icon"
|-phone: "253353309"
|-state: "blank"
|-uid: "2NUPkQuHFRS49ZHDZzEtWiErIiv1"
|-username: "not_busy"
|-F0NRthr8uJPYMz2o129w2PAf30i1
|-GRJPA5hKA6aRgNl68sSxv3xruww1
|-W0PIUjUwRHXTkooztYFuhKuLItE3
|-cBzUNHceM2T47cr0zWX1tqgB2wA3
It must be a small bug, but I still cannot figure what problem is.. thank you in advance.

Recylerview not visible in Android App

I have created a recyclerView in one of the fragments of my activity. And I am binding it to a dataset. I have set both the LinearLayoutManager and RecyclerView Adapter. My dataset is also getting created correctly and so is my Viewholder. There are no compilation warnings, no exceptions in my Logcat. I have checked the XML layouts for both fragment and the individual item and both are having all items set to Visible.
Yet my recyclerView is not showing in the fragment.
What are the common oversights resulting in recyclerView not being visible. Appreciate any guidance I can get on the matter.
Relevant Method initialising my recylerView is below:
private void loadMyPlacardView(View view){
List<Post> postList = new ArrayList<>();
RecyclerView placardsRecyclerView = view.findViewById(R.id.fp_placards_recyclerView);
LinearLayoutManager postsLayoutManager = new LinearLayoutManager(view.getContext());
placardsRecyclerView.setHasFixedSize(true);
placardsRecyclerView.setLayoutManager(postsLayoutManager);
DataSnapshot dataSnapshot = FirebaseStorageUtils.postDataSnapshot;
for (DataSnapshot singleSnapShot: dataSnapshot.getChildren()) {
Post thisPost = singleSnapShot.getValue(Post.class);
postList.add(thisPost);
}
PlacardsRecyclerViewAdapter placardsRecyclerViewAdapter = new PlacardsRecyclerViewAdapter(postList);
placardsRecyclerView.setAdapter(placardsRecyclerViewAdapter);
}
Code for the RecyclerviewAdapter is here
public class PlacardsRecyclerViewAdapter
extends RecyclerView.Adapter<PlacardHolder> {
private static final String TAG = "PlacardsViewAdapter";
private List<Post> listofPosts;
public PlacardsRecyclerViewAdapter(List <Post> list) {
listofPosts = list;
}
#Override
public PlacardHolder onCreateViewHolder(ViewGroup parent, int viewType){
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.placard_item, parent, false);
return new PlacardHolder(view);
}
#Override
public void onBindViewHolder(PlacardHolder placard, int position) {
Post currentPost = listofPosts.get(position);
String username = currentPost.getUserName();
placard.userName.setText(username);
}
#Override
public int getItemCount() {
return listofPosts.size();
}
}
Code for Recyclerviewholder as class PlacardHolder.java is below
public class PlacardHolder extends RecyclerView.ViewHolder {
private static final String TAG = "PlacardsHolder";
public TextView userName;
public PlacardHolder(View view){
super(view);
this.userName = view.findViewById(R.id.pi_profile_name);
}
}
XML for the Placard Item is placard_item.xml below
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:id="#+id/pi_profile_name"
android:text="#string/default_username"
android:textAlignment="center"
android:textSize="25sp"
android:textStyle="bold"
android:layout_weight="7"/></android.support.constraint.ConstraintLayout>
and code for fragment_placard.xml is
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="testing recyclerview"/>
<android.support.v7.widget.RecyclerView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/fp_placards_recyclerView"
android:scrollbars="vertical"
android:visibility="visible"
android:layout_margin="10dp">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
The textview from the fragment_placard.xml is loading fine but not the recyclerview.
Okay! It is about Firebase. You are not notifying your adapter after adding data to dataset. Do
if(placardsRecyclerViewAdapter != null)
placardsRecyclerViewAdapter.notifyDataSetChanged();
after adding data to postList.
Updated
Full structure:
private ValueEventListener postListener = null;
private void loadMyPlacardView(View view) {
List<Post> postList = new ArrayList<>();
RecyclerView placardsRecyclerView = view.findViewById(R.id.fp_placards_recyclerView);
LinearLayoutManager postsLayoutManager = new LinearLayoutManager(view.getContext());
placardsRecyclerView.setHasFixedSize(true);
placardsRecyclerView.setLayoutManager(postsLayoutManager);
PlacardsRecyclerViewAdapter placardsRecyclerViewAdapter = new PlacardsRecyclerViewAdapter(postList);
placardsRecyclerView.setAdapter(placardsRecyclerViewAdapter);
//Fetching data from Firebase
postListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChildren()) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
Post thisPost = ds.getValue(Post.class);
postList.add(thisPost);
}
if(placardsRecyclerViewAdapter != null)
placardsRecyclerViewAdapter.notifyDataSetChanged(); //Now postList has data so notify adapter.
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
Log.e("DB error", "loadPost:onCancelled", databaseError.toException());
}
};
databaseReference.addListenerForSingleValueEvent(valueEventListener);
}
I found the answer to my question. there were 2 bugs. First problem was in the placard_item.xml where I had declared the Constraintview as follows:
android:layout_height ="match parent"
because of this the layout was taking up the entire space in the screen. The second bug was that I had defined the TextView as below
android:layout_width = "0dp"
This was causing the TextView to disappear inside the recyclerview at run-time, although it was showing perfectly well in the "Design" view of my xml in AndroidStudio IDE. I am posting answer here in case someone else faces same issues. "ConstraintView" in general is proving hard to handle while working with Recyclerview. So going back to the simpler LinearLayout.

RecyclerView for chat app has display issue using Friebase realtime database

Left is Mary and right is Bill , the speaker's textView will show on the right side , the situation is that Mary says 1 and 2 , it looks fine , just like the photo:
next step : the right side device is Bill who says a and b , it looks fine that is just what i want.
when they type words more and more , my issue is happen like this:
But when i leave the ChatGroup1 and enter it again , it looks fine
So my issue is that it has something wrong with realtime on display recyclerView
How can i fix this issue , i try to add listData.clear(); , it's not working
Any help would be appreciated , thanks in advance .
It's my chat channel layout:
<?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">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerChat"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/button2">
</android.support.v7.widget.RecyclerView>
<Button
android:id="#+id/button2"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:background="#drawable/ic_send" />
<EditText
android:gravity="center"
android:hint="Type your message..."
android:background="#drawable/edit_corner"
android:id="#+id/editText2"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_toLeftOf="#+id/button2"
android:layout_toStartOf="#+id/button2" />
</RelativeLayout>
it's my chat class for Firebase and recyclerView:
//global variable
private RecyclerView recyclerChat;
private ArrayList<ChatItem> listData = new ArrayList<>();
private RecyclerChatItemAdapter adapter;
private DatabaseReference root;
About FirebaseDatabase:
root = FirebaseDatabase.getInstance().getReference().child(room_name);
//send message to FirebaseDatabase
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Map<String, Object> map = new HashMap<>();
temp_key = root.push().getKey();
root.updateChildren(map);
DatabaseReference message_root = root.child(temp_key);
Map<String, Object> map2 = new HashMap<>();
map2.put("name", user_name);
map2.put("msg", editText2.getText().toString());
message_root.updateChildren(map2);
manager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken() , InputMethodManager.HIDE_NOT_ALWAYS);//just hide the keyboard when send message
editText2.setText("");
}
});
I think that may be my issue is just right here , about my recyclerView:
root.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
ChatItem chatItem = dataSnapshot.getValue(ChatItem.class);//put the data to my javabean from Firebase
Log.d("Contacts: ", chatItem.toString());
listData.add(chatItem);
recyclerChat.scrollToPosition(adapter.getItemCount() - 1);//just let the latest data below
adapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
//append_right_chat_conversation(dataSnapshot);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
LinearLayoutManager manager = new LinearLayoutManager(this);
// GridLayoutManager gridLayoutManager=new GridLayoutManager(this,2);
manager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerChat.setLayoutManager(manager);
adapter = new RecyclerChatItemAdapter(this, listData);
recyclerChat.setAdapter(adapter);
adapter.notifyDataSetChanged();//when i leave the chat group and enter again , it looks fine because this.
It's my recyclerView adapter:
public class RecyclerChatItemAdapter extends RecyclerView.Adapter<RecyclerChatItemAdapter.MyViewHolder>{
private Context context;
private List<ChatItem> mDatas;
public RecyclerChatItemAdapter(Context context, List<ChatItem> mDatas) {
this.context = context;
this.mDatas = mDatas;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view=View.inflate(parent.getContext(),R.layout.for_chat_item_layout,null);
MyViewHolder myViewHolder=new MyViewHolder(view);
return myViewHolder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
String myName=mDatas.get(position).getName();
Contacts contacts=Contacts.getContacts();
String createName=contacts.getName();
if (myName.equals(createName)){
holder.textRight.setText(mDatas.get(position).getMsg()+"("+mDatas.get(position).getName()+")");
holder.textRight.setTextColor(Color.BLUE);
holder.textRight.setBackground(context.getResources().getDrawable(R.drawable.chat_green));
}else {
holder.textLeft.setText(mDatas.get(position).getMsg()+"("+mDatas.get(position).getName()+")");
holder.textLeft.setTextColor(Color.RED);
holder.textLeft.setBackground(context.getResources().getDrawable(R.drawable.chat_blue));
}
}
#Override
public int getItemCount() {
return mDatas.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder{
private TextView textLeft,textRight;
public MyViewHolder(View itemView) {
super(itemView);
textLeft=(TextView)itemView.findViewById(R.id.textLeft);
textRight=(TextView)itemView.findViewById(R.id.textRight);
}
}
}
You don't have shown Adapter layout and adapter code... It can be visibility problem of view.
You may be set visibility for view.. So for that please ensure that you have written something like this..
if (myName.equals(createName)){
holder.textRight.setVisibility(VISIBLE);
holder.textLeft.setVisibility(GONE);
holder.textRight.setText(mDatas.get(position).getMsg()+"("+mDatas.get(position).getName()+")");
holder.textRight.setTextColor(Color.BLUE);
holder.textRight.setBackground(context.getResources().getDrawable(R.drawable.chat_green));
}else {
holder.textRight.setVisibility(GONE);
holder.textLeft.setVisibility(VISIBLE);
holder.textLeft.setText(mDatas.get(position).getMsg()+"("+mDatas.get(position).getName()+")");
holder.textLeft.setTextColor(Color.RED);
holder.textLeft.setBackground(context.getResources().getDrawable(R.drawable.chat_blue));
}

Categories

Resources