отображение изображений хранилища firebase в RecyclerView

Привет, я задал ранее вопрос об отображении изображения с использованием Base64 из моей базы данных Firebase. Было рекомендовано использовать хранилище firebase. Я переработал свой код, и все загружается в хранилище и базу данных firebase, как и должно быть. Проблема, с которой я сталкиваюсь, заключается в том, что когда я сохраняю данные, ничего не заполняет мой recyclerview. Все пусто.

Любая помощь, которую вы можете мне оказать, чтобы заставить это работать, была бы отличной. Спасибо.

РЕДАКТИРОВАТЬ: в моем классе активности я вызываю прослушиватель кнопок, чтобы активировать камеру. После того, как снимок сделан, он сохраняется в хранилище Firebase. Затем я загружаю изображение из хранилища и отображаю его в recyclerview. Я понимаю часть загрузки, но мне трудно понять часть загрузки и отображения. Спасибо.

видхолдер: метод привязки

public void bind (ImageProgress progress){

    Glide.with(activity).load("").into(image);
 }
}

адаптер

  @Override
public ProgressViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
    return new ProgressViewHolder(activity, activity.getLayoutInflater().inflate(R.layout.weight_progress_list, parent, false));

основной класс деятельности

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.weight_progress);

    saveButton = (Button) findViewById(R.id.saveButton);
    progressStatusEditText = (EditText) findViewById(R.id.progressStatusEditText);
    progressList = (RecyclerView) findViewById(R.id.progressList);
    mImageButton = (ImageButton) findViewById(R.id.takePictureButton);
    capturedImage=(ImageView)findViewById(R.id.capturedImageView);

    LinearLayoutManager layoutManager = new LinearLayoutManager(this);
    progressList.setHasFixedSize(false);
    progressList.setLayoutManager(layoutManager);

    //take picture button
    mImageButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            openCamera();
        }
    });


    mDatabaseReference = database.getReference("Progress");

    saveButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //get current user
            FirebaseUser user =FirebaseAuth.getInstance().getCurrentUser();
            String uid = user.getUid();
            ImageProgress progress = new ImageProgress(uid, progressStatusEditText.getText().toString());
            mDatabaseReference.push().setValue(progress);
            progressStatusEditText.setText("");
        }
    });
}

private void openCamera() {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {

        Uri cameraImageURI = data.getData();
        //reference where images will be stored
        mStorageReference = storage.getReference("Progress Images");
        //reference to store file
        final StorageReference cameraImageRef = mStorageReference.child(cameraImageURI.getLastPathSegment());
        //upload to firebase storage
        cameraImageRef.putFile(cameraImageURI)
                .addOnSuccessListener(this, new OnSuccessListener<UploadTask.TaskSnapshot>() {
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                        Uri downloadUrl = taskSnapshot.getDownloadUrl();
                        progressStatusEditText.setText(downloadUrl.toString());
                    }
                });
}

person hozdaman    schedule 14.09.2016    source источник
comment
Приятно слышать, что вы перешли на использование Firebase Storage. Это должно масштабироваться намного лучше. Но здесь слишком много кода, чтобы мы могли быстро помочь. Вы, кажется, загружаете изображения, обрабатываете нажатия кнопок, читаете из базы данных и многое другое. Сократите это до минимального кода, необходимого для воспроизведения проблемы, и у нас будет больше шансов помочь вам.   -  person Frank van Puffelen    schedule 15.09.2016
comment
@FrankvanPuffelen Привет, Фрэнк, я отредактировал свой код, надеюсь, в чем заключается моя проблема. Я добавил больше описания моей проблемы. Заранее спасибо за вашу помощь.   -  person hozdaman    schedule 15.09.2016
comment
@FrankvanPuffelen Привет, мне интересно, была ли у тебя возможность взглянуть на мой отредактированный код? Спасибо.   -  person hozdaman    schedule 16.09.2016


Ответы (3)


Я предлагаю вам добавить метод setImage в ваш RecyclerView.ViewHolder и сохранить URL-адрес вашего изображения в объекте, который вы извлекаете в своем FirebaseRecyclerAdapter.

В моем случае я использую Glide для управления изображениями моего приложения:

Пример моего ViewHolder:

public class UserListViewHolder extends RecyclerView.ViewHolder {
private final View mView;
private static final int POST_TEXT_MAX_LINES = 6;
private ImageView mIconView;
private TextView mAuthorView;
private UserClickListener mListener;

public UserListViewHolder(View itemView) {
    super(itemView);
    mView = itemView;
    mIconView = (ImageView) mView.findViewById(R.id.user_image_profile);
    mAuthorView = (TextView) mView.findViewById(R.id.user_text_profile);
    mView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mListener.onUserClick();
        }
    });
}

public void setIcon(String url) {
    GlideUtil.loadProfileIcon(url, mIconView);//       
}

public void setPostClickListener(UserClickListener listener) {
    mListener = listener;
}


public void setText(final String text) {
    if (text == null || text.isEmpty()) {
        mAuthorView.setVisibility(View.GONE);
        return;
    } else {
        mAuthorView.setVisibility(View.VISIBLE);
        mAuthorView.setText(text);
        mAuthorView.setMaxLines(POST_TEXT_MAX_LINES);
    }
}

public interface UserClickListener {
    void onUserClick();
}
}

И вот мой вызов базы данных:

 private FirebaseRecyclerAdapter<Person, UserListViewHolder> getFirebaseRecyclerAdapter(Query query) {
    return new FirebaseRecyclerAdapter<Person, UserListViewHolder>(
            Person.class, R.layout.user_row_item, UserListViewHolder.class, query) {

        @Override
        protected void populateViewHolder(UserListViewHolder viewHolder, Person model, int position) {
            setupUser(viewHolder, model, position, null);
        }

    };
}

private void setupUser(final UserListViewHolder UserViewHolder, final Person user, final int position, final String inPostKey) {
    final String postKey;
    if (mAdapter instanceof FirebaseRecyclerAdapter) {
        postKey = ((FirebaseRecyclerAdapter) mAdapter).getRef(position).getKey();
    } else {
        postKey = inPostKey;
    }
    FirebaseUtil.getUsersRef().child(postKey).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(final DataSnapshot dataSnapshot) {
            UserViewHolder.setPostClickListener(new UserListViewHolder.UserClickListener() {
                @Override
                public void onUserClick() {
                    mGroup.addUserToGroup(dataSnapshot.getKey());
                }
            });
            UserViewHolder.setIcon(dataSnapshot.child("photoUrl").getValue(String.class));
            UserViewHolder.setText(dataSnapshot.child("displayName").getValue(String.class));

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}

Вам просто нужно установить изображение так же, как вы устанавливаете другие значения при извлечении данных из Firebase, но используя уже созданный новый URL-адрес для этого изображения после его загрузки в облако.

Возможно, вы можете найти другой способ просто установить URL-адрес, но я предлагаю вам сохранить его как еще один параметр в вашем пользовательском объекте, будучи динамическим, если вы хотите получить эти данные более одного раза, даже если вы не загружаете изображение.

person Francisco Durdin Garcia    schedule 22.09.2016
comment
Дурдин, пожалуйста, помогите мне, когда я загружаю изображение в firebase, оно успешно загружается, а также загруженное изображение дважды отображается в адаптере в пользовательском интерфейсе, почему? - person Erum; 19.12.2016

Для этой цели уже существует официальная реализация.

https://github.com/firebase/quickstart-android/tree/master/storage

Основная идея состоит в том, чтобы загрузить изображение в хранилище Firebase и сохранить URL-адрес изображения в базе данных, а затем загрузить его по этой ссылке.

В классе MyDownloadService.java использовался метод mStorageRef.child(downloadPath).getStream, но я реализовал метод getBytes, чтобы не иметь дело с входными потоками. Потому что можно легко загружать байты с помощью Glide. Когда задача завершена, она отправляет широковещательное намерение с байтами в виде пакета. Вы можете прослушивать вещательный приемник в любом месте, чтобы загрузить свое изображение, когда оно будет загружено.

public class DownloadService extends Service{

    private StorageReference mStorageRef;

    @Override
    public void onCreate() {
        super.onCreate();

        // Initialize Storage
        mStorageRef = FirebaseStorage.getInstance().getReference();

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
     if (ACTION_DOWNLOAD.equals(intent.getAction())) {


        mStorage.child(downloadPath).getBytes(10*1024*1024).addOnSuccessListener(new OnSuccessListener<byte[]>() {
            @Override
            public void onSuccess(byte[] bytes) {
                Log.d(TAG, "download:SUCCESS " + bytes.length);

                // Send success broadcast with number of bytes downloaded
                Intent broadcast = new Intent(ACTION_COMPLETED);
                broadcast.putExtra(EXTRA_DOWNLOAD_BYTES, bytes);
                broadcast.putExtra(EXTRA_DOWNLOAD_INDEX, uid);
                LocalBroadcastManager.getInstance(getApplicationContext())
                        .sendBroadcast(broadcast);

                // Mark task completed
                taskCompleted();
            }
        }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception exception) {
                    Log.w(TAG, "download:FAILURE", exception);

                    // Send failure broadcast
                    Intent broadcast = new Intent(ACTION_ERROR);
                    broadcast.putExtra(EXTRA_DOWNLOAD_PATH, downloadPath);
                    LocalBroadcastManager.getInstance(getApplicationContext())
                    .sendBroadcast(broadcast);

                    // Mark task completed
                    taskCompleted();
                }
            });
    }

    }
person ugur    schedule 22.09.2016

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

http://wptrafficanalyzer.in/blog/listview-with-images-and-text-using-simple-adapter-in-android/

???????????? Ссылка для создания адаптера списка с изображениями и текстом.

https://firebase.google.com/docs/storage/android/download-files

???????????? Ссылка для сохранения изображения firebase sorage во внешнюю память

вам просто нужно вызвать желаемое изображение для определенного представления в списке

person pratikpchpr    schedule 08.05.2017
comment
Для этих целей рекомендуется просмотр recyclerview больше, чем просмотр списка; в любом случае, если вы предлагаете какой-то ответ, дайте хотя бы немного инструкций или несколько ссылок. - person Brandon Zamudio; 08.05.2017