首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用实时数据库时使用不同的RecyclerView项布局

使用实时数据库时使用不同的RecyclerView项布局
EN

Stack Overflow用户
提问于 2017-07-20 02:04:26
回答 1查看 71关注 0票数 0

我希望在回收器视图中的项目被单击后,使用不同的数据(并采用不同的布局)填充回收器视图。用于填充回收器视图的数据来自firebase实时数据库。当一个项目被点击时,回收器视图应该显示所选节点的子节点。而不是开始一个新的活动并膨胀一个全新的布局。我想尝试更改单个布局的一部分。我认为在渲染、内存和电池性能方面可能会有性能上的好处(而且还有更小的apk,因为需要包含的文件更少)。我知道我需要分析代码,并将其与有多个活动的情况进行比较,但首先我想让代码在数据库中上下移动。我的MainFragment包含一个侦听器,它在recyclerview的Adapter类中调用(如下所示)。

代码语言:javascript
运行
复制
@Override
public void setItemLayoutResuorce(String key) {
    Log.i("Hilarity", "SILR");
    mMessagesDatabaseReference = mMessagesDatabaseReference.child(key);
    Log.i("Hilarity", mMessagesDatabaseReference.getKey());
    mChildEventListener = new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            if (mMessagesDatabaseReference.getKey().equals(getString(R.string.languages))) {
                String langauge = dataSnapshot.getKey();
                languages.add(langauge);
                jokeAdapter.notifyItemInserted(languages.size() - 1);
                jokeAdapter.notifyDataSetChanged();
                Log.i("Hilarity", "languages add");
            } else {
                Log.i("Hilarity", "joke added");
                Joke joke = dataSnapshot.getValue(Joke.class);
                jokes.add(joke);
                jokeAdapter.notifyItemInserted(jokes.size() - 1);
                jokeAdapter.notifyDataSetChanged();
            }
        }

        public void onChildChanged(DataSnapshot dataSnapshot, String s) {}
        public void onChildRemoved(DataSnapshot dataSnapshot) {}
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {}
        public void onCancelled(DatabaseError databaseError) {}
    };
    mMessagesDatabaseReference.addChildEventListener(mChildEventListener);
    jokeAdapter = new JokeAdapter(getActivity(), jokes, languages, this, true);
    recyclerview.setAdapter(jokeAdapter);

它在Adapter.ViewHolder.onClick()中调用(如下所示)

代码语言:javascript
运行
复制
@Override
    public void onClick(View view){
        if (view instanceof TextView) {
            showJokes = true;
            TextView textView = (TextView) view;
            rvc.setItemLayoutResuorce(textView.getText().toString());
        }
    }

当我单击一个回收器视图项,并且回收器视图需要重新填充数据,但是没有数据(还没有)时,致命的错误出现了,我在Adapter.onBindViewHolder中得到了一个索引越界异常。它就像childEventListener一样,即使在我创建的侦听器中重新实例化了(它最初是在MainFragment.onCreate()中创建的),也不会被重置。

如何让数据库在单击按钮后发送新数据(其他一切似乎都正常,使用了新的布局资源,我所需要的就是填充recyclerview的数据)?您认为用C++编写这部分代码并手动删除(然后创建)对DatabaseReference和ChildEventListener对象的引用会行得通吗?

EN

回答 1

Stack Overflow用户

发布于 2017-07-20 02:28:30

看起来你需要在后台线程中直接从数据源(在你的例子中是Firebase)更新你的RecyclerView内容。

最佳实践是在后台线程中收集您需要在RecyclerView中显示的所有数据,将其保存到UI线程上的本地副本(本地ArrayList或映射,取决于您的数据结构),并且仅在使用notifyDataSetChanged()或不同的更新方法从适配器请求内容更新之后。

在您的代码中,我还发现了多余的调用:

代码语言:javascript
运行
复制
jokeAdapter.notifyItemInserted(jokes.size() - 1);
jokeAdapter.notifyDataSetChanged();

不需要在调用notifyItemInserted()之后立即调用notifyDataSetChanged(),因为第一次更新应该更新适配器中从指定位置到最后一次的所有项。对notifyDataSetChanged的额外调用只是重复更新,但对所有项都是如此。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45197938

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档