FirebaseRecyclerAdapter - 如何在创建后更改数据库查询

时间:2016-08-03 16:51:12

标签: android firebase firebase-realtime-database firebaseui

问题

我有一个通过FirebaseRecyclerAdapter在Android中显示的项目列表。我创建了这个适配器,在所有项目列表上都有一个数据库引用(让我们说“帖子”)。帖子还显示了类别,如果用户点击该类别,我想更新列表以仅显示该类别的项目。

解决方案我尝试了无效 我在“类别”textview上放置了一个单击侦听器,当用户单击它时,我尝试使用新的数据库查询实例化一个新的适配器,但它不起作用。

其他想法: 在adpater之外做: 创建一个新的Intent以重新启动片段并使用新查询创建一个新的适配器

问题 有人处理相同的情况,在用户点击您要过滤由adpater检索的原始项目列表? 什么是最好的解决方案?

详情

protected void populateViewHolder(final PostViewHolder viewHolder, final Post post, final int position) {


    /* Set the post text, author and category */
    viewHolder.postText.setText(post.getText());
    viewHolder.postAuthor.setText(post.getAuthor());
    viewHolder.postCategory.setText(post.getCategory());

    /* Set a listener on category so that 
      I refresh data with only that category */
    viewHolder.quoteCategory.setOnClickListener(new View.OnClickListener() {

        Post selectedPost = getItem(position);

        @Override
        public void onClick(View v) {

            String category = selectedPost.getCategory();

            // !!!! NOW I HAVE TO CHANGE DATA SET !!! ///

我认为现在我可以创建一个带有正确Db引用的新适配器的新片段......但这是最好的方法吗? 有没有办法在填充视图中使用相同的Adapater传递另一个查询?

5 个答案:

答案 0 :(得分:2)

在使用新查询构建选项之后,可以使用updateOptions(options)。

updateOptions(newOptions)

样本

fun changeQuery() {
        val newQuery = mBaseQuery
            .orderByChild("timestamp")
            .limitToLast(100)

        // Make new options
        val newOptions = FirebaseRecyclerOptions.Builder<Post>()
            .setQuery(newQuery, Post::class.java)
            .build()

        // Change options of adapter.
        mAdapter.updateOptions(newOptions)
    }

Reference

答案 1 :(得分:1)

点击发生时,尝试在适配器上调用.notifyDatasetChanged()。使用新的firebase数据更改数据集后。

答案 2 :(得分:1)

您不会更改查询,创建新的适配器和查询,在Recycler视图中替换适配器,并清理旧的。

这是一个例子,&#34;更改查询&#34;根据微调器中的选择:

   locationSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(final AdapterView<?> adapterView, final View view,
         final int i, final long l) {
            if (locationSpinner.getSelectedItem() != null) {
                final Location location = locationSpinner.getSelectedItem();
                final String indexString = String.format("open/%s/", location.getId());
                final Query query = FirebaseDatabase.getInstance()
                        .getReference("availabilities")
                        .orderByChild("statusLocationDateKey")
                        .startAt(indexString + "0") // simplified for example
                        .endAt(indexString + "9"); // simplified for example
                adapter = new ListingAdapter(query);
                final FirebaseRecyclerAdapter oldAdapter = 
                        (FirebaseRecyclerAdapter) listing.getAdapter();
                listing.setAdapter(adapter);
                if (oldAdapter != null) {
                    oldAdapter.cleanup();
                }
            }
        }

注意:ListingAdapterFirebaseRecyclerAdapter的子类,listingRecyclerView

还要确保在on destroy中包含空检查 对于活动或片段,因为使用上面的代码,无法保证适配器曾被初始化,例如:

@Override
public void onDestroyView() {
    if (adapter != null) {
        adapter.cleanup();
    }
    super.onDestroyView();
}

答案 3 :(得分:1)

如果要在创建后更改数据库查询,则需要stopListening到适配器,然后使用新查询创建新的适配器,并startListening到适配器

示例代码如下

FirebaseRecyclerAdapter fireBaseAdapter;
RecyclerView recyclerView;

 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.your_layout, container, false);


locationSpinner.setOnItemSelectedListener(this);
Query query = databaseReference.child("yourChild").orderByChild("keyName");

    getDataFireBase(query);

    return view;
}

public void getDataFireBase(final Query query) {
    if (fireBaseAdapter!= null)
        fireBaseAdapter.stopListening();       


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

    fireBaseAdapter= new FirebaseRecyclerAdapter(options);
    recyclerView.setAdapter(fireBaseAdapter);
    fireBaseAdapter.startListening();
}



 @Override
    public void onItemSelected(final AdapterView<?> adapterView, final View view, final int i, final long l) {



Query query = databaseReference.child("yourChild").orderByChild("keyName"); // your new query

    getDataFireBase(query);




        }

 @Override
public void onStart() {
    super.onStart();
    fireBaseAdapter.startListening();
}

@Override
public void onStop() {
    super.onStop();
    fireBaseAdapter.stopListening();
}

答案 4 :(得分:0)

以下是更新firebase数据的代码。这里我更新了两个参数,传递给title和body。

private void writeNewPost(String userId, String username, String title, String body) {

        String key = mDatabase.child("posts").push().getKey();
        Post post = new Post(userId, username, title, body);
        Map<String, Object> postValues = post.toMap();

        Map<String, Object> childUpdates = new HashMap<>();
        childUpdates.put("/posts/" + key, postValues);
        childUpdates.put("/user-posts/" + userId + "/" + key, postValues);

        mDatabase.updateChildren(childUpdates);
    }

我认为这会对你有所帮助。