Firebase实时数据库不在Recyclerview中显示图像

时间:2020-09-29 19:35:04

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

我是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>

这是我的数据库结构。

enter image description here

更新 所以我更改了代码以适合数据结构

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

现在输入这个作为我的数据结构。我该怎么做才能获得上述格式? enter image description here

3 个答案:

答案 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属性设为私有。