简体   繁体   English

在RecyclerView中显示firebase存储映像

[英]displaying firebase storage images in a RecyclerView

Hi I asked an earlier question about displaying an image using Base64 from my Firebase database. 您好我之前询问过有关使用Firebase数据库中的Base64显示图像的问题。 It was recommended to use firebase storage. 建议使用firebase存储。 I reworked my code and everything loads into the firebase storage and databse as it should. 我重新编写了代码,所有内容都加载到firebase存储和数据库中。 The issue I have is when I save the data nothing populates into my recyclerview. 我遇到的问题是当我保存数据时,没有任何内容填充到我的recyclerview中。 Everything is blank. 一切都是空白的。

Any help you can provide me to get this to work would be great. 你可以提供给我这个工作的任何帮助都会很棒。 Thanks. 谢谢。

EDIT: In my activity class I am calling a button clicklistener to activate the camera. 编辑:在我的活动类中,我调用一个按钮clicklistener来激活相机。 Once the picture is taken it is saved to Firebase Storage. 拍摄照片后,它将保存到Firebase存储。 Then I download it the image from Storage and display it in a recyclerview. 然后我从存储中下载图像并将其显示在recyclerview中。 I understand the uploading portion but I am having difficulty understanding the downloading and displaying portion. 我理解上传部分,但我很难理解下载和显示部分。 Thanks. 谢谢。

viewholder:bind method viewholder:绑定方法

public void bind (ImageProgress progress){

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

adapter 适配器

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

main activity class 主要活动课

@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());
                    }
                });
}

I suggest you add setImage method on your RecyclerView.ViewHolder and store the url of your image in the object that you retrieve in your FirebaseRecyclerAdapter . 我建议你在RecyclerView.ViewHolder上添加setImage方法,并将你的图像的url存储在你在FirebaseRecyclerAdapter检索的对象中。

In my case, I'm using a Glide to manage the images of my app: 在我的情况下,我使用Glide来管理我的应用程序的图像:

My ViewHolder Example: 我的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();
}
}

And here is my database call: 这是我的数据库调用:

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

        }
    });
}

You just need to set the image in the same way that you set your others values when retrieving data from Firebase, but using your already generated newURL for that image after upload it to the cloud. 您只需要在从Firebase检索数据时设置图像的方式与设置其他值相同,但在将图像上传到云后使用已生成的newURL。

Maybe you can find another way to just set the url, but I suggest you to keep it like another parameter in your custom object, being dynamic if you want to retrieve that data more than once even if you are not uploading the image. 也许您可以找到另一种方法来设置网址,但我建议您将其保留为自定义对象中的另一个参数,如果您想要多次检索该数据,即使您没有上传图像也是如此。

There is already an official implementation for this purpose. 为此目的已经有正式实施。

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

The basic idea is to upload the image to the firebase storage and the store the image url to the database and then download it via this link. 基本思想是将图像上传到firebase存储,并将图像URL存储到数据库,然后通过此链接下载。

In the MyDownloadService.java class mStorageRef.child(downloadPath).getStream method was used but i implemented with getBytes method not to deal with inputstreams. 在MyDownloadService.java类中使用了mStorageRef.child(downloadPath).getStream方法,但我用getBytes方法实现了不处理输入流的方法。 Because can load bytes with Glide easily. 因为可以轻松地用Glide加载字节。 When the task is completed, it sends a broadcast intent with bytes as bundle. 任务完成后,它会发送一个包含字节的广播意图。 You can listen the broadcast receiver wherever u want in order to load ur image when it is downloaded. 您可以在任何地方收听广播接收器,以便在下载时加载图像。

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

    }

Use Custom list adapter to handle listview and to handle imageView use GLIDE which provides simple method's to load images with storage link. 使用自定义列表适配器来处理列表视图和处理imageView使用GLIDE,它提供了使用存储链接加载图像的简单方法。

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

👆👆👆 Link to create list adapter with and imageview and textview 👆👆👆使用和imageview和textview创建列表适配器的链接

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

👆👆👆 Link to save firebase sorage image to external memory 👆👆👆链接将firebase sorage映像保存到外部存储器

you just need to call desired image to particular view in listview 您只需要将所需的图像调用到listview中的特定视图

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM