【问题标题】:Firebase Realtime Database not displaying images in RecyclerviewFirebase 实时数据库未在 Recyclerview 中显示图像
【发布时间】:2021-01-15 11:15:49
【问题描述】:

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

现在我把它作为我的数据结构。我该怎么做才能以上述格式获取它?

【问题讨论】:

    标签: java android firebase firebase-realtime-database android-recyclerview


    【解决方案1】:

    您的数据库实际上在TopsFolder 节点下存储了String 的列表,您需要将它们作为字符串列表获取。因此,我建议您在 GetDataFromFirebase 函数中更改您的 onDataChange 实现,如下所示。

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

    这应该可以解决您的问题。

    【讨论】:

      【解决方案2】:

      您不能将存在于TopsFolder 节点下的对象映射到Tops 类型的对象,因为这些对象实际上都不代表Tops 类型的对象。但是,如果您需要将每个对象映射到 Tops 对象,则需要像这样重构架构:

      Firebase-root
         |
         --- TopsFolder
               |
               --- pushedId
               |     |
               |     --- top: "https://..."
               |
               --- pushedId
                     |
                     --- top: "https://..."
      

      这样TopsFolder下的每个对象就代表一个Tops对象。看,属性的名称是“top”,就像在你的 Tops 类中一样,“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);
      

      请不要忘记在您的 Tops 类中将 top 属性设为私有。

      【讨论】:

      • 您好,感谢您的回复。很抱歉,我应该在我的 TopsActivity.java 中进行哪些更改,以便我的图像按照您显示的结构存储在实时数据库中。感谢您的宝贵时间
      • 请检查我更新的答案并告诉我它是否有效。
      • 您好,我做了一些更改,您能检查一下我对我的问题所做的更新并帮助我吗?非常感谢
      • 不,还是不正确!键应始终为“top”,作为类中的属性名称,NOT Top 1Top 2 等。一个孩子应该只包含一个top: "https://...",因为你的类中只有一个属性,好吗?
      • 很抱歉,您能否告诉我要在代码中进行哪些更改以获得您提到的结构,因为在应用程序中,用户应该从手机图库中选择图像并将它们上传到firebase。我不能使用 Tops tops = new Tops("https://...");
      【解决方案3】:

      您可以使用毕加索图书馆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);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-15
        相关资源
        最近更新 更多