Bonjour, j'ai posé une question précédente sur l'affichage d'une image à l'aide de Base64 à partir de ma base de données Firebase. Il a été recommandé d'utiliser le stockage Firebase. J'ai retravaillé mon code et tout se charge dans le stockage Firebase et la base de données comme il se doit. Le problème que j'ai est que lorsque j'enregistre les données, rien ne se trouve dans ma vue de recyclage. Tout est vide.
Toute aide que vous pouvez me fournir pour que cela fonctionne soit formidable. Merci.
EDIT: Dans ma classe d'activité, j'appelle un écouteur de clic pour activer la caméra. Une fois la photo prise, elle est enregistrée dans Firebase Storage. Ensuite, je télécharge l'image du stockage et l'affiche dans une vue de recyclage. Je comprends la partie de téléchargement, mais j'ai du mal à comprendre la partie de téléchargement et d'affichage. Merci.
viewholder: méthode bind
public void bind (ImageProgress progress){
Glide.with(activity).load("").into(image);
}
}
adaptateur
@Override
public ProgressViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
return new ProgressViewHolder(activity, activity.getLayoutInflater().inflate(R.layout.weight_progress_list, parent, false));
classe d'activité principale
@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());
}
});
}
Je vous suggère d'ajouter la méthode setImage sur votre RecyclerView.ViewHolder
et stockez l'url de votre image dans l'objet que vous récupérez dans votre FirebaseRecyclerAdapter
.
Dans mon cas, j'utilise un Glide pour gérer les images de mon application:
Mon exemple de 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();
}
}
Et voici mon appel de base de données:
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) {
}
});
}
Il vous suffit de définir l'image de la même manière que vous définissez vos autres valeurs lors de la récupération des données de Firebase, mais en utilisant votre nouvelle URL déjà générée pour cette image après l'avoir téléchargée sur le cloud.
Vous pouvez peut-être trouver une autre façon de définir simplement l'URL, mais je vous suggère de le conserver comme un autre paramètre dans votre objet personnalisé, en étant dynamique si vous souhaitez récupérer ces données plusieurs fois même si vous ne téléchargez pas l'image.
Il existe déjà une implémentation officielle à cet effet.
https://github.com/firebase/quickstart-Android/tree/master/storage
L'idée de base est de télécharger l'image sur le stockage Firebase et de stocker l'URL de l'image dans la base de données, puis de la télécharger via ce lien.
Dans la classe MyDownloadService.Java, la méthode mStorageRef.child (downloadPath) .getStream a été utilisée mais j'ai implémenté la méthode getBytes pour ne pas traiter les flux d'entrée. Parce que peut charger des octets avec Glide facilement. Une fois la tâche terminée, elle envoie une intention de diffusion avec des octets en tant que groupe. Vous pouvez écouter le récepteur de diffusion où vous le souhaitez afin de charger votre image lorsqu'elle est téléchargée.
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();
}
});
}
}
Utilisez l'adaptateur de liste personnalisé pour gérer listview et pour gérer imageView, utilisez GLIDE qui fournit une méthode simple pour charger des images avec un lien de stockage.
http://wptrafficanalyzer.in/blog/listview-with-images-and-text-using-simple-adapter-in-Android/
???????????? Lien pour créer l'adaptateur de liste avec et imageview et textview
https://firebase.google.com/docs/storage/Android/download-files
???????????? Lien pour enregistrer l'image de stockage Firebase dans la mémoire externe
il vous suffit d'appeler l'image souhaitée pour une vue particulière dans la liste