Слушатель добавляет только последнее изображение в списке в RecyclerView - PullRequest
0 голосов
/ 18 декабря 2018

Я получаю снимок данных идентификаторов пользователя.Эти идентификаторы также идентичны идентификаторам изображений соответствующих профильных изображений пользователей.Я хочу заполнить RecyclerView каждым изображением, которое совпадает с RecyclerView, но в результате получается, что он заполняет правильный идентификатор пользователя, но он заполняет только последнее изображение в списке снимка данных вместо всех.В итоге я получаю список идентификаторов пользователей и одно изображение внизу:

    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);

Вот как это выглядит:

Only one image

Это адаптер:

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

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

Поскольку getDownloadUrl - это асинхронный метод, другие объекты пользователя изменяются, и при вызове onSuccess () вызывается только последний объект, поэтому последние объекты устанавливаются на URI.

  1. Использование HashMap<String,User> userMap = new HashMap<String,User>();

  2. До getDownloadUrl

    userMap.put(imageName,user);

  3. in onSuccess ()

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

Сделать imageName окончательным.

0 голосов
/ 18 декабря 2018

Ваша переменная "user" не может использоваться таким образом внутри метода обратного вызова onSuccess ().Эта переменная всегда ссылается на ПОСЛЕДНЕЕ «new User ()», поэтому, когда процедура «download» достигает значения «onSuccess ()», значением «user» является САМОЕ ПОСЛЕДНЕЕ выполненное «new User ()».Вам нужно передать что-то вроде «userID» в метод загрузки, и когда выполняется «onSuccess ()», вы должны найти нужного пользователя, используя этот ID, а затем установить его изображение.

...