【问题标题】:using different RecyclerView item layout when working with real time database使用实时数据库时使用不同的 RecyclerView 项目布局
【发布时间】:2017-07-20 21:56:35
【问题描述】:

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

@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() 中调用(如下所示)

@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 对象的引用是否可行?

【问题讨论】:

    标签: android firebase firebase-realtime-database


    【解决方案1】:

    您似乎正在处理直接从后台线程中的数据源(在您的情况下为 Firebase)更新您的 RecyclerView 内容。

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

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

    jokeAdapter.notifyItemInserted(jokes.size() - 1);
    jokeAdapter.notifyDataSetChanged();
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-25
      • 2016-12-06
      • 1970-01-01
      • 1970-01-01
      • 2021-12-29
      • 2021-01-19
      • 2016-02-19
      • 1970-01-01
      相关资源
      最近更新 更多