我是Android的新手,我正在开发一个显示用户上传的衣服图像的应用。我可以完美上传图片,但是由于某些原因,无法将Firebase实时数据库中的图片显示到RecyclerView
中。我已经在寻找解决方案好几个星期了。
请帮帮我。非常感谢您抽出宝贵的时间。
TopActivity.java
public class TopActivity extends AppCompatActivity {
FloatingActionButton fab;
//Uploading Images to Firebase
private static final int PICK_IMAGE = 1;
private Uri ImageUri;
ArrayList ImageList = new ArrayList();
private int upload_count = 0;
private ProgressDialog progressDialog;
ArrayList urlStrings;
List<String> imagesEncodedList;
Uri uri,mImageUri;
String imageEncoded;
ArrayList<Uri> mArrayUri = new ArrayList<>();
RecyclerView recyclerView;
DatabaseReference databaseReference,dbreference;
private ArrayList<Tops> topslist;
private TopsAdapter topsAdapter;
private Context mContext;
StorageReference ImageFolder,Folder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_top);
fab = findViewById(R.id.fab);
recyclerView=findViewById(R.id.recyclerView);
GridLayoutManager gridLayoutManager=new GridLayoutManager(TopActivity.this,2);
recyclerView.setLayoutManager(gridLayoutManager);
recyclerView.setHasFixedSize(true);
topslist = new ArrayList<>();
GetDataFromFirebase();
progressDialog = new ProgressDialog(TopActivity.this);
progressDialog.setMessage("Uploading Images Please Wait");
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
startActivityForResult(intent,PICK_IMAGE);
}
});
}
private void uploadImage(){
urlStrings = new ArrayList<>();
progressDialog.show();
ImageFolder = FirebaseStorage.getInstance().getReference().child("Tops");
for (upload_count = 0; upload_count < mArrayUri.size(); upload_count++) {
Uri IndividualImage = (Uri) mArrayUri.get(upload_count);
final StorageReference ImageName = ImageFolder.child("Top_" + IndividualImage.getLastPathSegment());
ImageName.putFile(IndividualImage).addOnSuccessListener(
new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
ImageName.getDownloadUrl().addOnSuccessListener(
new OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri uri) {
urlStrings.add(String.valueOf(uri));
if (urlStrings.size() == mArrayUri.size()) {
storeLink(urlStrings);
}
}
}
);
}
}
);
}
}
private void storeLink(ArrayList<String> urlStrings) {
HashMap<String,String > hashMap = new HashMap<>();
for (int i = 0; i <urlStrings.size() ; i++) {
hashMap.put("Top "+i, urlStrings.get(i));
}
databaseReference = FirebaseDatabase.getInstance().getReference("TopsFolder");
databaseReference.push().setValue(hashMap)
.addOnCompleteListener(
new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(TopActivity.this, "Successfully Uploaded", Toast.LENGTH_SHORT).show();
}
}
}
).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Toast.makeText(TopActivity.this, "" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
progressDialog.dismiss();
ImageList.clear();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
try {
if (requestCode == PICK_IMAGE && resultCode == RESULT_OK
&& null != data) {
imagesEncodedList = new ArrayList<String>();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
if (data.getData() != null) {
mImageUri = data.getData();
// Get the cursor
Cursor cursor = getContentResolver().query(mImageUri,
filePathColumn, null, null, null);
// Move to first row
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
imageEncoded = cursor.getString(columnIndex);
cursor.close();
uploadImage();
} else {
if (data.getClipData() != null) {
ClipData mClipData = data.getClipData();
for (int i = 0; i < mClipData.getItemCount(); i++) {
ClipData.Item item = mClipData.getItemAt(i);
uri = item.getUri();
mArrayUri.add(uri);
// Get the cursor
Cursor cursor = getContentResolver().query(uri, filePathColumn, null, null, null);
// Move to first row
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
imageEncoded = cursor.getString(columnIndex);
imagesEncodedList.add(imageEncoded);
cursor.close();
}
Log.v("LOG_TAG", "Selected Images" + mArrayUri.size());
uploadImage();
}
}
} else {
Toast.makeText(this, "You haven't picked Image",
Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Toast.makeText(this, "Something went wrong", Toast.LENGTH_LONG)
.show();
}
super.onActivityResult(requestCode, resultCode, data);
}
private void GetDataFromFirebase(){
//Query query=databaseReference.child("TopsFolder/Tops");
//query.addValueEventListener(new ValueEventListener() {
databaseReference = FirebaseDatabase.getInstance().getReference();
dbreference=databaseReference.child("TopsFolder");
ValueEventListener eventListener = new ValueEventListener() {
@Override
public void onDataChange( DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
Tops tops=ds.child("TopsFolder").getValue(Tops.class);
topslist.add(tops);
}
topsAdapter= new TopsAdapter(getApplicationContext(),topslist);
recyclerView.setAdapter(topsAdapter);
topsAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
};
dbreference.addListenerForSingleValueEvent(eventListener);
}
}
TopsAdapter.java
public class TopsAdapter extends RecyclerView.Adapter<TopsAdapter.ViewHolder> {
private static final String Tag="RecyclerView";
private Context mContext;
private ArrayList<Tops> topslist;
public TopsAdapter(Context mContext, ArrayList<Tops> topslist) {
this.mContext = mContext;
this.topslist = topslist;
}
@NonNull
@Override
public TopsAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext())
.inflate(R.layout.top_rv_item,parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Glide.with(mContext)
.load(topslist.get(position).getTop())
.into(holder.ivTopGallery);
}
@Override
public int getItemCount() {
return topslist.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
ImageView ivTopGallery;
public ViewHolder(@NonNull View itemView) {
super(itemView);
ivTopGallery=itemView.findViewById(R.id.ivTopGallery);
}
}
}
Tops.java
public class Tops {
//Model Class
public String top;
//Constructors
public Tops(){}
public Tops(String top) {
this.top = top;
}
public String getTop() {
return top;
}
public void setTop(String top) {
this.top = top;
}
}
top_rv_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_height="150dp"
android:layout_width="150dp"
android:padding="10dp"
android:id="@+id/ivTopGallery"
android:scaleType="fitXY"
/>
</LinearLayout>
这是我的数据库结构。
更新 所以我更改了代码以适合数据结构
Firebase-root
|
--- TopsFolder
|
--- pushedId
| |
| --- top: "https://..."
|
--- pushedId
|
--- top: "https://..."
这是我在TopsActivity.java中所做的更改
private void storeLink(ArrayList<String> urlStrings) {
HashMap<String, String> hashMap = new HashMap<>();
databaseReference = FirebaseDatabase.getInstance().getReference("TopsFolder");
for (int i = 1; i <urlStrings.size() ; i++) {
hashMap.put("Top "+i, urlStrings.get(i));
databaseReference.push().setValue(hashMap);
}
progressDialog.dismiss();
Toast.makeText(TopActivity.this, "Successfully Uploaded", Toast.LENGTH_SHORT).show();
ImageList.clear();
}
答案 0 :(得分:1)
您的数据库实际上在String
节点下存储了TopsFolder
的列表,您需要将它们作为字符串列表来获取。因此,我建议按如下方式在onDataChange
函数中更改您的GetDataFromFirebase
实现。
@Override
public void onDataChange( DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
// You should have the elements as an array of string.
Tops[] tops = ds.child("TopsFolder").getValue(Tops[].class);
if (topList != null) toplist.clear(); // Clear the list if there's anything already in the list
topslist = Arrays.asList(tops); // Assign the items to the list from the array that you retrieved from firebase database.
}
topsAdapter= new TopsAdapter(getApplicationContext(), topslist);
recyclerView.setAdapter(topsAdapter);
topsAdapter.notifyDataSetChanged();
}
那应该可以解决您的问题。
答案 1 :(得分:0)
您可以使用Picasso库implementation 'com.squareup.picasso:picasso:2.5.2'
这对我有用。
public static void setUrlImageInView(Context context, String url, ImageView view) {
// (optional) use Picasso to download and show to image
Picasso.with(context).load(url).into(view);
}
要考虑的另一件事是您再次从同一个孩子那里获取数据。在示例案例中,您必须使用文档ID
Tops tops=ds.child("-MIPf9A2H_.....").getValue(Tops.class);
topslist.add(tops);
答案 2 :(得分:0)
您无法将TopsFolder
节点下存在的对象映射为Tops
类型的对象,因为这些对象实际上都不代表Tops
类型的对象。但是,如果您需要将每个对象映射到Tops
对象中,则需要像这样重新构建架构:
Firebase-root
|
--- TopsFolder
|
--- pushedId
| |
| --- top: "https://..."
|
--- pushedId
|
--- top: "https://..."
这样,TopsFolder
下的每个对象都代表一个Tops
对象。就像在Tops
类中一样,属性的名称为“ top”,而“ value”是实际的URL。所需的代码应如下所示:
@Override
public void onDataChange( DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String url = ds.getValue(String.class);
if (topList != null) toplist.clear(); // Clear the list if there's anything already in the list
topslist.add(url);
}
topsAdapter= new TopsAdapter(getApplicationContext(), topslist);
recyclerView.setAdapter(topsAdapter);
topsAdapter.notifyDataSetChanged();
}
编辑:
Tops tops = new Tops("https://...");
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference topFolderRef = rootRef.child("TopsFolder");
topFolderRef.push().setValue(tops);
也请不要忘记在您的top
类中将Tops
属性设为私有。