我遵守Android development team provided的ViewModel实施准则。但是,我得到了意想不到的结果。我一直在挖掘互联网,但没有运气。
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);
}
}
预期结果: 启用后的应用会打开MainActivity,并在回收者视图中显示书籍。
实际结果: 启动应用程序后,MainActivity将不显示任何内容。单击后,返回应用程序关闭。单击应用程序图标以将其打开时,它将启动进入显示MainActivity的工作,该活动显示了重复的书籍数据集。
Link to gif showing the outcome.
谁能找到问题所在?为什么onCreate第一次不初始化适配器?为什么我会得到重复的书籍清单?
答案 0 :(得分:1)
让我们细分您所写的内容以及LiveData如何处理您的问题吗?
首先,您的适配器看起来不错(大部分情况下),这不是这里的问题。
让我们看一下ViewModel以及这里出了什么问题,请内联阅读我的评论以获取解决方案:
public class BookViewModel extends ViewModel {
private List<BookMarketPojo> booksList = new ArrayList<>();
private final String NODE_NAME = "_books_for_sale_";
private FirebaseDatabase db = FirebaseDatabase.getInstance();
/**
* The purpose of livedata is to simply emit events.
* Therefore this can be simply written as [note the general convention used in naming]
*/
public MutableLiveData<List<BookMarketPojo>> onBookListUpdated = MutableLiveData<List<BookMarketPojo>>();
/**
* The problem with this code, is that when you set the value initially, you only set an empty arraylist.
* Remember, your LiveData is only a way to emit changes to a data (the data here being booksList) with the safetynet of LifeCycle Awareness
* therefore, to fetch the data, we only need to do this.
*/
public void getData() {
fetchData()
}
private void fetchData() {
db.getReference(NODE_NAME).addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
//To remove duplicates, make sure the book isn't already present in the list. Exercise is left to you
booksList.add(dataSnapshot.getValue(BookMarketPojo.class));
//This will now trigger the livedata, with the list of the books.
onBookListUpdated.setValue(booksList)
}
@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) {
}
});
}
}
最后是您的Activity的OnCreate()
bookViewModel.onBookListUpdated.observe(this, books -> {
myAdapter.notifyDataSetChanged();
});
另外,请查看Reading Data Once的Firebase实时数据库文档,因为我认为只取一次书就更适合您的用例了!