1

I'm following a tutorial from less than 3 months ago, so I'm assuming it can't be outdated already. I'm using a FirebaseRecyclerAdapter in my Android project. Currently I'm trying to search books stored in my Firebase and return a matching Book, in my searchBook method I'm using a FirebaseRecyclerAdapter. However when I declare my FirebaseRecyclerAdapter = new Firebas... I'm being forced to implemented two methods, onBindviewHolder and onCreateViewHolder. I don't think I need these, or if I do, can someone explain to me why I might?

Currently this is my code:

private void searchBook(){


    FirebaseRecyclerAdapter<Book, BookViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Book, BookViewHolder>(

            Book.class,
            R.layout.listview_booksearchresults,
            BookViewHolder.class,
            bookDatabase

    ) {
        protected void populateViewHolder(BookViewHolder viewHolder, Book model, int position){

            viewHolder.setDetails(model.getTitle(), model.getAuthor(), model.getImageURL());
        }
    };

    mResultList.setAdapter(firebaseRecyclerAdapter);

}

And if I click to implement these two methods, my code becomes error ridden like there's no tomorrow.

Code after implementing methods:

private void searchBook(){


    FirebaseRecyclerAdapter<Book, BookViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Book, BookViewHolder>(

            Book.class,
            R.layout.listview_booksearchresults,
            BookViewHolder.class,
            bookDatabase

    ) {
        @NonNull
        @Override
        public BookViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            return null;
        }

        @Override
        protected void onBindViewHolder(@NonNull BookViewHolder holder, int position, @NonNull Book model) {

        }

        protected void populateViewHolder(BookViewHolder viewHolder, Book model, int position){

            viewHolder.setDetails(model.getTitle(), model.getAuthor(), model.getImageURL());
        }
    };

    mResultList.setAdapter(firebaseRecyclerAdapter);

}

This is my first time using a RecyclerAdapter so I'm very new to the concept. Hoping this is just a rookie error! Where am I going wrong and why?

This is my updated onCreate method:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(activity_searchbook);




    bookDatabase = FirebaseDatabase.getInstance().getReference("All_Books");

    searchField = (EditText) findViewById(R.id.book_Title);
    search = (Button) findViewById(R.id.searchBookButton);

    mResultList = (RecyclerView) findViewById(R.id.result_List);
    mResultList.setHasFixedSize(true);
    mResultList.setLayoutManager(new LinearLayoutManager(this));



        DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("All_Books");
        Query query = ref.orderByChild("title").equalTo(searchField.toString());

        FirebaseRecyclerOptions<Book> options =
                new FirebaseRecyclerOptions.Builder<Book>()
                        .setQuery(query, Book.class)
                        .build();


        FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter<Book, BookViewHolder>(options) {
            @Override
            public BookViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                // Create a new instance of the ViewHolder, in this case we are using a custom
                // layout called R.layout.message for each item
                View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listview_booksearchresults, parent, false);

                return new BookViewHolder(view);

            }

            @Override
            protected void onBindViewHolder(BookViewHolder holder, int position, Book model) {
                holder.setDetails(model.getTitle(), model.getAuthor(), model.getImageURL());
            }
        };
        mResultList.setAdapter(adapter);
    }
Eoghan Casey
  • 190
  • 3
  • 17

1 Answers1

1

You are using the newest Firebaseui version, there is no populateViewHolder anymore, you need to do the following:

First, configure the adapter by building FirebaseRecyclerOptions. Book is your POJO class and then query will be the data that should be shown in the recyclerview.

DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("users");
Query query=ref.orderByChild("name").equalTo(name);

FirebaseRecyclerOptions<Book> options =
            new FirebaseRecyclerOptions.Builder<Book>()
                    .setQuery(query, Book.class)
                    .build();

Then create the FirebaseRecyclerAdapter object:

 FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter<Book, BookViewHolder>(options) {
@Override
public BookViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    // Create a new instance of the ViewHolder, in this case we are using a custom
    // layout called R.layout.message for each item
    View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.message, parent, false);

    return new BookViewHolder(view);
}

@Override
protected void onBindViewHolder(BookViewHolder holder, int position, Book model) {
    // Bind the Book object to the BookViewHolder
    // ...
  }
};

more info here:

https://github.com/firebase/FirebaseUI-Android/tree/master/database#using-firebaseui-to-populate-a-recyclerview

Peter Haddad
  • 78,874
  • 25
  • 140
  • 134
  • I have bound my Book object like so, protected void onBindViewHolder(BookViewHolder holder, int position, Book model) { holder.setDetails(model.getTitle(), model.getAuthor(), model.getImageURL()); } Is this incorrect? – Eoghan Casey Apr 02 '18 at 21:41
  • It needs to be `holder.setTitle(model.getTitle())` `holder.setAuthor(model.getAuthor())` `holder.setImageURL(model.getImageURL())` the `title,author,imageURL` should be fields in your POJO class – Peter Haddad Apr 02 '18 at 21:47
  • I'm still having an error here. It's saying "No adapter attached; skipping layout" - although I have mResultList.setAdapter(adapter); . Do you know why this is the case? – Eoghan Casey Apr 03 '18 at 10:38
  • check this: https://stackoverflow.com/questions/43869606/firebase-recyclerview-no-adapter-attached-skipping-layout – Peter Haddad Apr 03 '18 at 10:41
  • If I do that then it's not letting me put this code within a method, and I want to be able to call this method in an onClickListener... Thanks for you help on this. – Eoghan Casey Apr 03 '18 at 10:49
  • where are you attaching and initializing the adapter? – Peter Haddad Apr 03 '18 at 10:54
  • Initializing the adapter in the oncreate method, and attaching the adapter just after the onBindViewHolder. All of the code is no in the onCreate method. I have shown such in my updated question above for you – Eoghan Casey Apr 03 '18 at 10:56
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/168108/discussion-between-peter-haddad-and-eoghan-casey). – Peter Haddad Apr 03 '18 at 10:56