0

The following code when i put inside Firebase's addChildEventListener -> onChildAdded overrided function, is working, instead of myRecyclerViewAdapter.notifyDataSetChanged()

expendableRecyclerViewAdapter = new ExpendableRecyclerViewAdapter(listOfItems, getContext());
mExpandableRecyclerView.setAdapter(expendableRecyclerViewAdapter);

The following function is working 'No adapter attached; skipping layout' Error is being displaying in the logcat what is the problem here? Any help is appreciated

    private boolean getCurrentRestMenuList(){
        DatabaseReference databaseReference = firebaseDatabase.getReference("menus").child(restID);
        databaseReference.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {

                MenuModelForFirebase menuModel = dataSnapshot.getValue(MenuModelForFirebase.class);
                MenuModel expandableMenuModel = new MenuModel(menuModel.getMenuTitle(), menuModel.getFoodModelList());
                listOfMenus.add(expandableMenuModel);

                expendableRecyclerViewAdapter = new ExpendableRecyclerViewAdapter(listOfMenus, getContext());
                mExpandableRecyclerView.setAdapter(expendableRecyclerViewAdapter);


            }

            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {

            }

            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {

            }

            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String s) {

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
        return listOfMenus.isEmpty();
}

ERROR WHEN RecyclerViewAdapter.notifyDataSetChanged() called inside firebase's addchildeventlistener -> onChildAdded

01-04 06:48:31.907 30495-30495/com.example.aliy.bisp_client_side E/AndroidRuntime: FATAL EXCEPTION: main
                                                                               Process: com.example.aliy.bisp_client_side, PID: 30495
                                                                               java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
                                                                                   at com.thoughtbot.expandablerecyclerview.models.ExpandableList.numberOfVisibleItemsInGroup(ExpandableList.java:37)
                                                                                   at com.thoughtbot.expandablerecyclerview.models.ExpandableList.getVisibleItemCount(ExpandableList.java:50)
                                                                                   at com.thoughtbot.expandablerecyclerview.ExpandableRecyclerViewAdapter.getItemCount(ExpandableRecyclerViewAdapter.java:93)

Menu Model For Firebase

public class MenuModelForFirebase {

private String MenuTitle;
private List<FoodModel> foodModelList;

public MenuModelForFirebase(){}

public MenuModelForFirebase(String menuTitle, List<FoodModel> foodModelList) {
    MenuTitle = menuTitle;
    this.foodModelList = foodModelList;
}

public String getMenuTitle() {
    return MenuTitle;
}

public void setMenuTitle(String menuTitle) {
    MenuTitle = menuTitle;
}

public List<FoodModel> getFoodModelList() {
    return foodModelList;
}

public void setFoodModelList(List<FoodModel> foodModelList) {
    this.foodModelList = foodModelList;
}

}

Food Model

    package com.example.aliy.bisp_client_side.Models;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * Created by Aliy on 12/31/2017.
 */

public class FoodModel implements Parcelable {



private String fId;
private String fName;
private int fPrice;
private String fDescription;
private String fCuisineType;
private String fFoodImage;


public FoodModel(String fId, String fName, int fPrice, String description, String fCuisineType, String fFoodImage) {
    this.fId = fId;
    this.fName = fName;
    this.fPrice = fPrice;
    this.fDescription = description;
    this.fCuisineType = fCuisineType;
    this.fFoodImage = fFoodImage;
}

public FoodModel() {

}


protected FoodModel(Parcel in) {
    fId = in.readString();
    fName = in.readString();
    fPrice = in.readInt();
    fDescription = in.readString();
    fCuisineType = in.readString();
    fFoodImage = in.readString();
}

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel parcel, int i) {
    parcel.writeString(fId);
    parcel.writeString(fName);
    parcel.writeInt(fPrice);
    parcel.writeString(fDescription);
    parcel.writeString(fCuisineType);
    parcel.writeString(fFoodImage);
}

public static final Creator<FoodModel> CREATOR = new Creator<FoodModel>() {
    @Override
    public FoodModel createFromParcel(Parcel in) {
        return new FoodModel(in);
    }

    @Override
    public FoodModel[] newArray(int size) {
        return new FoodModel[size];
    }
};



public String getfId() {
    return fId;
}

public String getfName() {
    return fName;
}

public int getfPrice() {
    return fPrice;
}

public String getfDescription() {
    return fDescription;
}

public String getfCuisineType() {
    return fCuisineType;
}

public String getfFoodImage() {
    return fFoodImage;
}

public void setfFoodImage(String fFoodImage) {
    this.fFoodImage = fFoodImage;
}

public void setfCuisineType(String fCuisineType) {
    this.fCuisineType = fCuisineType;
}

public void setfId(String fId) {
    this.fId = fId;
}

public void setfName(String fName) {
    this.fName = fName;
}

public void setfPrice(int fPrice) {
    this.fPrice = fPrice;
}

public void setfDescription(String fDescription) {
    this.fDescription = fDescription;
}
}

Menu Model For Expandable Recycler View

public class MenuModel extends ExpandableGroup<FoodModel> {

public MenuModel(String title, List<FoodModel> items) {
    super(title, items);
}

}

The fragment that has expandable recycler view

    @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_restaurant__menu, container, false);
    SetRestID();
    //Set visible Brand Icon and Restaurant Imageview layouts
    ((Home_Screen)getActivity()).showImageviewAndBrandIcon();


    //region TITLE INIT
    collapsingToolbarLayout = (CollapsingToolbarLayout) getActivity().findViewById(R.id.collapsingToolbarLayout);
    //endregion

    //region CHANGE TITLE TEXTVIEW COLORS
    collapsingToolbarLayout.setCollapsedTitleTextColor(getResources().getColor(R.color.PALETTE_AMBER));
    collapsingToolbarLayout.setExpandedTitleColor(getResources().getColor(R.color.white));
    //endregion

    //region APP BAR LAYOUT WITH SETTING BEHAVIOUR TO BRAND ICON
    appBarLayout = (AppBarLayout) getActivity().findViewById(R.id.main_home_page_app_bar_layout);
    appBarLayout.addOnOffsetChangedListener(this);
    //endregion

    //region BRAND ICON LAYOUT INIT
    brand_icon = (LinearLayout) getActivity().findViewById(R.id.brand_icon);
    YoYo.with(Techniques.ZoomInUp).duration(2000).playOn(brand_icon);
    //endregion

    //region FIREBASE INITIALIZING
    firebaseDatabase = FirebaseDatabase.getInstance();
    //endregion

    //region SETTING UP IMAGEVIEWS and Textviews
    SetupLayout(view);
    //endregion

    //region GET RESTAURANT DATA FROM DB
    getCurrentRestaurantInfo();
    //endregion



    //region CONTENT PART -- RETRIEVING RESTAURANTS MENUS FROM DB
    mExpandableRecyclerView =  view.findViewById(R.id.expandable_recycler_menu);
    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
    layoutManager.setAutoMeasureEnabled(true);
    mExpandableRecyclerView.setLayoutManager(layoutManager);

    listOfMenus= new ArrayList<>();
    mExpandableRecyclerView.setNestedScrollingEnabled(false);
    getCurrentRestMenuList();
    //endregion

    //region SETUP DEFAULT IMAGES TO SCREEN
    setupImageViewToDefaultImages();
    //endregion

    return view;
}
Aliy
  • 406
  • 6
  • 21

1 Answers1

0

You should understand 2 things here,

  1. ChildEventListener is async. You can not return true or false in your function according to the values you have retrieved from the childeventlistener.

  2. You don't have to attach new object of an adapter every time you update your dataset for recyclerview.

Here are the changes that I would suggest :

List<MenuModel> listOfMenus = new ArrayList();
expendableRecyclerViewAdapter = new ExpendableRecyclerViewAdapter(listOfMenus, getContext());
mExpandableRecyclerView.setAdapter(expendableRecyclerViewAdapter);
private void getCurrentRestMenuList(){
    listOfMenus.clear();
    DatabaseReference databaseReference = firebaseDatabase.getReference("menus").child(restID);
    databaseReference.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {

            MenuModelForFirebase menuModel = dataSnapshot.getValue(MenuModelForFirebase.class);
            MenuModel expandableMenuModel = new MenuModel(menuModel.getMenuTitle(), menuModel.getFoodModelList());
            listOfMenus.add(expandableMenuModel);
            expendableRecyclerViewAdapter.notifyDataSetChanged();// This will notify the adapter to reload the values for update the recyclerview.



        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {

        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
    //return listOfMenus.isEmpty();It might always return false because childeventlistener is an async. call. I don't see the use of this. 
}

If you have a specific use case in mind then please add it to the question.

mark922
  • 1,136
  • 2
  • 11
  • 20
  • It gives me the error I have posted above)) have u tried urself? It does not work – Aliy Jan 04 '18 at 10:53
  • Yes. It is working perfectly fine. Can you share your MenuModelForFirebase, MenuModel and the complete activity class code ? – mark922 Jan 04 '18 at 10:57
  • Do you it is expandable recyclerview not just recyclerview – Aliy Jan 04 '18 at 10:58
  • This is working code but keep showing No attached adapter. Skipping Layout - Message in the Logcat – Aliy Jan 04 '18 at 18:29
  • This might help : https://stackoverflow.com/questions/29141729/recyclerview-no-adapter-attached-skipping-layout – mark922 Jan 05 '18 at 04:21
  • You haven't set any adapter to the recyclerview here in OnCreateView(). Check your code. You have set the layout but forgot to set the adapter. – mark922 Jan 05 '18 at 04:23
  • I have set it in my getCurrentRestMenist() function – Aliy Jan 05 '18 at 13:56
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/162607/discussion-between-mark922-and-aliy). – mark922 Jan 05 '18 at 14:22
  • Ok Let’s go then)) – Aliy Jan 05 '18 at 14:53