【问题标题】:Listener only adds last image in list to the RecyclerView侦听器仅将列表中的最后一个图像添加到 RecyclerView
【发布时间】:2019-05-18 21:29:32
【问题描述】:

我得到了用户 ID 的数据快照。这些 id 也与匹配的用户头像的图像 id 相同。 我想用与 RecyclerView 匹配的每个图像填充 RecyclerView,但发生的是,它填充了正确的用户 ID,但它只填充数据快照列表中的最后一个图像,而不是全部。所以我最终得到了一个用户 ID 列表和底部的单个图像:

    ValueEventListener eventListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for(DataSnapshot ds : dataSnapshot.getChildren()) {
                imageName = ds.getKey();                   
                user = new User(imageName);
                myDataset.add(user);

                storageReference.child("profileImages").child(imageName).getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                    @Override
                    public void onSuccess(Uri uri) {


                        user.setImageUri(uri);
                        // Got the download URL                            
                        mAdapter.notifyDataSetChanged();

                    }
                }).addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception exception) {
                        // Handle any errors                            
                    }
                });
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {}
    };
    imagesRef.addListenerForSingleValueEvent(eventListener);

看起来是这样的:

这是适配器:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

    private ArrayList<User> mDataset;
    private MyViewHolder myHolder;
    private User user;

    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    // you provide access to all the views for a data item in a view holder
    public static class MyViewHolder extends RecyclerView.ViewHolder {

        public TextView userIdTextView;
        public ImageView userProfileImageView;
        public View layout;
        public MyViewHolder(View v) {
            super(v);
            layout = v;
            userProfileImageView = (ImageView) v.findViewById(R.id.profile_image);

        public TextView userIdTextView = (TextView) v.findViewById(R.id.user_id_text_view);
        }
    }

    // Provide a suitable constructor (depends on the kind of dataset)
    public MyAdapter(ArrayList<User> myDataset) {
        mDataset = myDataset;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
                                                     int viewType) {


        View v =  LayoutInflater.from(parent.getContext())
                .inflate(R.layout.recycler_view, parent, false);

        MyViewHolder vh = new MyViewHolder(v);
        return vh;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        myHolder = holder;
        user = mDataset.get(position);
        Uri userImage = user.getImageUri();
        myHolder.userIdTextView.setText(user.getUsername());

        Glide.with(myHolder.itemView.getContext() /* context */)
                .load(userImage)
                .apply(new RequestOptions().override(300, 300))
                .into(myHolder.userProfileImageView);


    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return mDataset.size();
    }

}

数据库结构:

database
   |_____users
           |___uid1 
           |___uid2
           |___uid3

【问题讨论】:

  • 提供您的适配器代码,以便我们构思
  • 请添加您的数据库结构,也请回复@AlexMamo
  • @AlexMamo 添加了数据库结构和适配器。问题不在于数据库结构,因为我得到了正确的用户名(我最初使用 Logging 进行了检查)
  • @sStacker 为什么不直接存储图片 url 而不是图片名称?

标签: android firebase firebase-realtime-database android-recyclerview firebase-storage


【解决方案1】:

您的“用户”变量不能在“onSuccess()”回调方法中以这种方式使用。该变量始终引用最后一个“new User()”,因此当“下载”过程到达“onSuccess()”时,“user”值的值是最新执行的“new User()”。您需要将“userID”之类的内容传递给下载方法,并且在执行“onSuccess()”时,您必须使用该 ID 找到正确的用户,然后设置其图像。

【讨论】:

  • 我不知道该怎么做,我从哪里开始
  • 对了,用户id和imageName一样,那么从这里我能做什么呢?
【解决方案2】:

由于 getDownloadUrl 是异步方法,因此更改了其他用户对象,并且在调用 onSuccess() 时仅引用了最后一个对象,因此设置了最后一个对象 uri。

  1. 使用HashMap&lt;String,User&gt; userMap = new HashMap&lt;String,User&gt;();

  2. getDownloadUrl 之前

    userMap.put(imageName,user);

  3. onSuccess()

    User user = userMap.get(imageName); user.setImageUri(uri);

使 imageName 最终化。

【讨论】:

  • 我不明白在我的代码中放置每个位置,你能帮我更多吗?我只是不明白我需要在哪里使用它。另外,如果 imageName 总是在变化,它怎么可能是最终的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-19
  • 2021-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多