【问题标题】:Recycler View only showing after I press an Edit Text仅在我按下编辑文本后才显示回收站视图
【发布时间】:2019-04-13 18:38:00
【问题描述】:

我有一个带有搜索栏(编辑文本)和下面的回收器视图的片段。为了显示我的回收站视图,我使用了一个适配器。我正在尝试显示用户的所有朋友。问题是回收站视图项目不会出现,除非我在搜索栏中点击(不输入任何内容)。
此外,当将我的数据库中的图像加载到图像视图中时,它们会混淆。
我的数据库如下:

{
 "Friends": {
            "id3":{
                "id1": "name1",
                "id2": "name2",
                ...
            },
            "id4":{
                "id1": "name1",
                "id3": "name3",
                ...
            }, ...
 },
 "Users": {
          "id1":{
             info about user1
          },
          "id2":{
             info about user2
          },
          "id3":{
             info about user3
          },
          "id4":{
             info about user4
          }, ...
 }
}

我调试了一下,发现我的 onCreateViewHolder 在创建片段时永远不会被调用(不确定这是否相关)。
我还尝试使用另一个查询来简单地显示数据库中的所有用户(因此只需遍历节点“用户”的子节点)。那确实有效,所以我想问题出在我的查询上。但是我不知道哪里出错了。

如何将我的回收站视图链接到我的适配器:

recyclerView = view.findViewById(R.id.frag_invite_recycler);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));

searchBar = view.findViewById(R.id.frag_invite_search_bar);

mUsers = new ArrayList<>();
mAdapter = new EventUserAdapter(getContext(),mUsers);
recyclerView.setAdapter(mAdapter);

我的好友查询:

Query friends = FirebaseDatabase.getInstance().getReference("Friends").child(firebaseUser.getUid()).orderByValue();

friends.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                mUsers.clear();

                for (DataSnapshot snp : dataSnapshot.getChildren()) {

                    Query users = FirebaseDatabase.getInstance().getReference("Users").child(snp.getKey());

                    users.addValueEventListener(new ValueEventListener() {
                        @Override
                        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                            User user = dataSnapshot.getValue(User.class);

                            assert user != null;
                            mUsers.add(user);
                        }
                        @Override
                        public void onCancelled(@NonNull DatabaseError databaseError) {
                        }
                    });
                }
                mAdapter.notifyDataSetChanged();
            }
            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
            }
        });

我的适配器:

@NonNull
    @Override
    public EventViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.user_event, viewGroup, false);

        return new EventViewHolder(view, mListener);
    }

    @Override
    public void onBindViewHolder(@NonNull EventViewHolder eventViewHolder, int i) {
        firebaseUser = FirebaseAuth.getInstance().getCurrentUser();

        final User user = mUsers.get(i);

        eventViewHolder.username.setText(user.getUsername());
        if (user.getImgURL() != null) Glide.with(eventViewHolder.icon.getContext()).load(user.getImgURL()).into(eventViewHolder.icon);

    }

    @Override
    public int getItemCount() {
        return mUsers.size();
    }

我的 ViewHolder:

public class EventViewHolder extends RecyclerView.ViewHolder {

        public TextView username;
        public ImageView check;
        public CircleImageView icon;

        public EventViewHolder(@NonNull View itemView, final onItemClickListener listner) {
            super(itemView);
            username = itemView.findViewById(R.id.user_event_name);
            icon = itemView.findViewById(R.id.user_event_image);
            check = itemView.findViewById(R.id.user_event_check);
    }
}

【问题讨论】:

  • 我不明白你对它是否工作的质疑,以及有什么问题。你能改写一下吗?
  • 好吧,当我打开片段时,回收站视图是空的。然后,每当我点击搜索栏(不写任何内容)时,回收站视图就会被填充。但是,我希望在创建片段后立即显示所有数据(而不仅仅是在点击搜索栏之后)。
  • 但是您说过,一旦您添加了一个显示所有用户的查询,该应用程序就会正常运行。从我所在的位置来看,最初的问题是您在创建EventUserAdapter 适配器后没有用内容填充recyclerview,但仅在使用editText 时才填充。因此,最初显示所有用户的查询解决了这个问题。你还需要什么?
  • 上面提供的查询最初是在来自 EditText 的 OnTextChange 之前调用的。所以它应该出现在我输入搜索栏之前,对吧?我还注意到 mAdapter.notifyDataSetChanged() 直到我使用搜索栏后才更新适配器内的值。
  • 如果您在活动创建时调用查询(onCreate、onStart 等),无论您是否在 editText 中输入任何内容,它都应该出现。当您调用mAdapter.notifyDataSetChanged() 时,它实际上是调用onBindViewHolder 来获取当前显示的视图。您的 onBindViewHolder 方法对我来说似乎很好,您从当前视图的位置获取数据并正确更新视图。检查在您执行notifyDataSetChanged(使用日志或调试)之后是否调用了此方法。如果调用它,问题可能出在其他地方。

标签: android android-fragments android-recyclerview


【解决方案1】:

我认为问题出在 我的朋友查询 部分中mAdapter.notifyDataSetChanged();
的位置。
您正在从users.addValueEventListener 的内部回调之外调用命令,这可能为时过早,您的用户数组刚刚被清除且尚未填充。

尝试做类似的事情:

friends.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        mUsers.clear();
        mAdapter.notifyDataSetChanged(); // for the current views actually reset
        // you could also do mAdpater.notifyItemRangeRemoved(0, mUsers.size()) but before clearing the list of course

        for (DataSnapshot snp : dataSnapshot.getChildren()) {

            Query users = FirebaseDatabase.getInstance().getReference("Users").child(snp.getKey());

            users.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    User user = dataSnapshot.getValue(User.class);

                    assert user != null;
                    mUsers.add(user);
                    mAdapter.notifyItemInserted(mUsers.size() - 1); // to display the current user in the recyclerview
                }
                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {
                }
            });
        }
    }
    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
    }
});

如果仍然无法正常工作,也许您正在使用两个不同的用户列表,一个在活动中,第二个在适配器中?检查您是保存原始列表的引用还是根据原始值生成新列表(在适配器的构造函数中)。然后,更新 Activity 的列表不会影响适配器的列表。

希望这能解决你的问题!

【讨论】:

  • 确实,我似乎在错误的地方调用了我的 notifyDataSetChanged。我还做了一些改进,以便您可以简单地调用 mAdapter.add(item),然后直接将一个项目添加到适配器中的列表中,然后调用 notifyDataSetChanged。非常感谢您的帮助:)
猜你喜欢
  • 2020-09-05
  • 1970-01-01
  • 1970-01-01
  • 2015-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多