I'm following ViewModel implementation guidelines as per Android development team provided. However, I'm getting unexpected results. I have been digging the internet but no luck.
BookMarketPojo.java
class BookMarketPojo {
private String bookTitle;
private String bookAuthor;
private String bookDescription;
private String bookPictureUrl;
private String ownerId;
private boolean sold;
public BookMarketPojo() {
}
public BookMarketPojo(String bookTitle, String bookAuthor, String bookDescription, String bookPictureUrl, String ownerId, boolean sold) {
this.bookTitle = bookTitle;
this.bookAuthor = bookAuthor;
this.bookDescription = bookDescription;
this.bookPictureUrl = bookPictureUrl;
this.ownerId = ownerId;
this.sold = sold;
}
// getters and setters
}
BookViewModel.java
public class BookViewModel extends ViewModel {
private List<BookMarketPojo> booksList = new ArrayList<>();
private final String NODE_NAME = "_books_for_sale_";
private FirebaseDatabase db = FirebaseDatabase.getInstance();
public MutableLiveData<List<BookMarketPojo>> getData() {
fetchData();
MutableLiveData<List<BookMarketPojo>> data = new MutableLiveData<>();
data.setValue(booksList);
return data;
}
private void fetchData() {
db.getReference(NODE_NAME).addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
booksList.add(dataSnapshot.getValue(BookMarketPojo.class));
}
@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) {
}
});
}
}
BookMarketAdapter.java
public class BookMarketAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<BookMarketPojo> bookMarketPojos;
public BookMarketAdapter(Context context, List<BookMarketPojo> bookMarketPojos) {
this.context = context;
this.bookMarketPojos = bookMarketPojos;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(context).inflate(R.layout.book_market_row, parent, false);
return new ViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
final BookMarketPojo book = bookMarketPojos.get(position);
((ViewHolder) viewHolder).title.setText(book.getBookTitle());
((ViewHolder) viewHolder).author.setText(book.getBookAuthor());
((ViewHolder) viewHolder).description.setText(book.getBookDescription());
Picasso.get().load(book.getBookPictureUrl()).into(((ViewHolder) viewHolder).bookImg);
}
@Override
public int getItemCount() {
return bookMarketPojos.size();
}
private class ViewHolder extends RecyclerView.ViewHolder {
TextView title, author, description;
ImageView bookImg;
public ViewHolder(View convertView) {
super(convertView);
title = convertView.findViewById(R.id.tv_title);
author = convertView.findViewById(R.id.tv_author);
description = convertView.findViewById(R.id.tv_description);
bookImg = convertView.findViewById(R.id.iv_bookImg);
}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MarketActivity";
private BookMarketAdapter myAdapter;
private RecyclerView recyclerView;
private BookViewModel bookViewModel;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.rv_bookMarket);
bookViewModel = new ViewModelProvider(this).get(BookViewModel.class);
bookViewModel.getData().observe(this, books -> {
myAdapter.notifyDataSetChanged();
});
initRecyclerView();
}
public void initRecyclerView(){
myAdapter = new BookMarketAdapter(this, bookViewModel.getData().getValue());
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(myAdapter);
}
}
Expected result: App on launch opens MainActivity and displays the books inside a recycler view.
Actual Result: App on launch opens MainActivity displays no content. When clicked return app closes. When clicked on app icon to open it launches into displaying MainActivity showing duplicated dataset of books.
Link to gif showing the outcome.
Can anyone spot where is the problem? Why onCreate does not initialize the adapter on the first go? And why I get a duplicated list of books?