Хранилище Android Firebase, загрузка внутреннего класса в растровое изображение

У меня проблемы со списком Android. У меня есть метод, который создает список игроков и загружает игроков из базы данных и хранилища firebase.

У некоторых игроков есть изображения профиля, и они хранятся как сгенерированный ключ в storage/players/keyname (уникальный ключ игрока в базе данных - это имя изображения профиля в хранилище Firebase).

У меня проблема, когда я пытаюсь создать OnSuccessListener / player. Я просто не могу передать данные.

Проблемы с onSuccessListener:

  • Все, что находится снаружи, считается «внешним классом», что означает, что когда я хочу создать проигрыватель, он не может читать данные внутри onsuccesslistener.
  • все внутри не может передавать данные за пределы слушателя.
  • Я не могу преобразовать его в растровое изображение

Мне нужно создать «Player p» с данными от слушателя и записи карты. Пока что я проиграл (не могу пройти оба).

//Method to create the list of players. To do: call again after adding new player
public void createPlayerList(){
    //The list of players that will be filled
    final List listPlayers = new ArrayList<Player>();

    //The path where all our players are stored.
    DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("users")
            .child( FirebaseAuth.getInstance().getCurrentUser().getUid() ).child("team").child("players");


    //Method that just gets called once
    ref.addListenerForSingleValueEvent(new ValueEventListener() {

        //dataSnapshot contains all data from the path to our players
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Map<String, Object> players = (Map<String, Object>) dataSnapshot.getValue();

            //We return our player data in a map. Loop through each value in the map and create a player object for each player
            //And add that player object to our list of players

            //Create Storage instance
            FirebaseStorage storage = FirebaseStorage.getInstance();
            //Create storageReference
            final StorageReference storageRef = storage.getReferenceFromUrl("gs://bucket.appspot.com");

            // Create a reference to a file from a Google Cloud Storage URI
            StorageReference gsReference = storage.getReferenceFromUrl(storageRef + "/players/");


            for (Map.Entry<String, Object> entry : players.entrySet()){
                Map singlePlayer = (Map) entry.getValue();

                //Get unique key
                String key = entry.getKey();

                storageRef.child(key).getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                    @Override
                    public void onSuccess(Uri uri) {
                        //Picasso.with(getActivity()).load(uri).into(R.id.playerProfilePicture);
                    }
                }).addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception exception) {
                        // Handle any errors
                    }
                });

                //standard mage
                Bitmap profileBits = BitmapFactory.decodeResource(getResources(), R.drawable.player_icon);
                PlayersFragment.this.setProfilePicture(profileBits);

                //Create player
                Player p = new Player((String) singlePlayer.get("name"), (String) singlePlayer.get("preferredPosition"), profilePicture   );

                //Add player to list
                listPlayers.add(p);
            }
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });

    //Add all results from database to our listview
    listViewPlayers = (ListView) fragmentView.findViewById(R.id.players_list);

    //Attach adapter to listview, to get a layout for each row
    listViewPlayers.setAdapter(new PlayerAdapter(getActivity(), R.layout.row_player_list_item, listPlayers));
    //Necessary for handling clicks
    listViewPlayers.setItemsCanFocus(true);

}

person user1692823    schedule 21.10.2016    source источник


Ответы (1)


Помните, что addListenerForSingleValueEvent возвращается немедленно. Слушатель, который вы ему передаете, будет вызван через некоторое время. В его нынешнем виде, похоже, вы ожидаете, что он будет заблокирован, пока не будет доступен результат и пока listPlayers не будет полностью заполнен.

Вместо этого я предлагаю работать со listViewPlayers из вашего обратного вызова onDataChange сразу после того, как станет известно, что ваш список игроков заполнен.

Также обратите внимание, что gsReference нигде не используется. Вы уверены, что не хотели сказать gsReference.child(key).getDownloadUrl()... искать в папке "Players" каждого найденного игрока в цикле?

person Doug Stevenson    schedule 22.10.2016