显示Android和Firebase的图片列表

时间:2018-01-18 16:16:50

标签: android firebase firebase-realtime-database

在我回答我的问题之前,只需对我的项目进行快速解释,这样你就可以得到所有内容的要点。 我目前正在使用Android和Firebase处理这个房地产应用程序。我一直在使用Firebase存储我的应用数据并对用户进行身份验证。 我可以将房地产对象添加到数据库中,并在列表视图中检索所有添加的房地产。当我点击一个列表项时,我得到了更详细的房地产版本。房地产的详细信息显示在四个不同的标签中。在其中一个标签中,我向用户提供了将图片等附件添加到房地产中的机会。 我添加了添加图片的功能。它们存储在数据库中,如以下屏幕截图所示。

eBncv5ke05ZxR32AiRoP9gSyPkO2是user_id和 " -L38Qe8GEo33i5roKOCi"房地产ID。键是图像的名称和URL的值。

以下代码显示了如何将图片添加到数据库中:

private void saveImage() {

    // get the expose id
    bundle = getArguments();
    immoID = bundle.getString("exposeID");
    Toast.makeText(getContext(), immoID, Toast.LENGTH_SHORT).show();


    // get an reference to the current user and his id
    user = FirebaseAuth.getInstance().getCurrentUser();
    user_id = user.getUid();

    imageName = imageNameInput.getText().toString();

    if (!TextUtils.isEmpty(imageName)) {

        //displaying progress dialog while image is uploading
        final ProgressDialog progressDialog = new ProgressDialog(getContext());
        progressDialog.setTitle("Bild wird hochgeladen");
        progressDialog.show();



        // uploading the Picture
        pictureStorageRef = FirebaseStorage.getInstance().getReference(user_id).child(Constants.STORAGE_PATH_UPLOADS).child(immoID);
        pictureDataRef = FirebaseDatabase.getInstance().getReference(Constants.DATABASE_PATH_UPLOADS).child(user.getUid()).child(immoID);
        //checking if file is available
        if (filePath != null) {


            //getting the storage reference
            StorageReference sRef = pictureStorageRef.child(Constants.STORAGE_PATH_UPLOADS + System.currentTimeMillis() + "." + getFileExtension(filePath));

            //adding the file to reference
            sRef.putFile(filePath)
                    .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                        @Override
                        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {


                            String imageName = imageNameInput.getText().toString().trim();
                            String imageDownloadURL = taskSnapshot.getDownloadUrl().toString();

                            //creating the upload object to store uploaded image details
                            PictureUpload upload = new PictureUpload(imageName, imageDownloadURL);


                            //adding an upload to firebase database
                            pictureDataRef.child(imageName).setValue(imageDownloadURL);
                            string_immo_image_url = imageDownloadURL;


                            //dismissing the progress dialog
                            progressDialog.dismiss();

                            changeFragment();


                        }
                    })
                    .addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception exception) {
                            progressDialog.dismiss();
                            Toast.makeText(getContext(), exception.getMessage(), Toast.LENGTH_LONG).show();
                        }
                    })
                    .addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
                        @Override
                        public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
                            //displaying the upload progress
                            double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
                            progressDialog.setMessage(((int) progress) + "% wurden hochegeladen");
                        }
                    });
        }
    }else{
        imageNameInput.setError("Geben Sie einen Namen ein");
        imageNameInput.requestFocus();

    }
}

现在我试图在Glide的片段中使用ListView来展示图片。因此,我为ListView AttachmentList

添加了一个适配器
public class AttachmentList extends ArrayAdapter <PictureUpload> {

List <PictureUpload> pictureUploads;
DatabaseReference pictureDatabase;
FirebaseUser user;
String userid;
private Activity context;

// Constructor
public AttachmentList (Activity context, List<PictureUpload> pictureUploads){
    super (context, R.layout.layout_expose_list, pictureUploads);
    this.context = context;
    this.pictureUploads = pictureUploads;

}

@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
    // inflate the custom layout for the listitems
    LayoutInflater inflater= context.getLayoutInflater();
    final View listViewItem = inflater.inflate(R.layout.layout_expose_list, null, true);

    // get the data item for this position
    PictureUpload pictureUpload = pictureUploads.get(position);


    user = FirebaseAuth.getInstance().getCurrentUser();
    userid = user.getUid();


    // get references to the view elements in the layout for populating the data
    TextView textViewTitle = listViewItem.findViewById(R.id.imageNameDisplay);
    ImageView attachmentImage = listViewItem.findViewById(R.id.attachmentImage);


    // set the most relevant information of the immo object to the textviews
    textViewTitle.setText(pictureUpload.getName());

    Glide.with(getContext()).load(pictureUpload.getUrl()).into(attachmentImage);


    // return the listview item to render
    return listViewItem;
}
}

PictureUpload类如下所示:

public class PictureUpload {

public String name;
public String url;

// Default constructor required for calls to
// DataSnapshot.getValue(User.class)
public PictureUpload() {
}

public PictureUpload(String name, String url) {
    this.name = name;
    this.url = url;
}

public String getName() {
    return name;
}

public String getUrl() {
    return url;
}
}

以下是Fragment的代码,我试图显示该列表:

package com.webgalaxie.blischke.bachelortakesix.fragments.tabfragments;



public class AttachmentTabFragment extends Fragment {
private static final String TAG = "ATTACHMENT_TAB";

FirebaseUser user;
String user_id;

Bundle bundle, newBundle;
String immoID;

// Button to add Attachments to the Expose
Button addAtachments;

private DatabaseReference immoDataRef, pictureDataRef, contactDataRef;
private StorageReference pictureStorageRef;


ListView show_all_attachments_list;
List<PictureUpload> pictureUploads;

public AttachmentTabFragment() {
    // Required empty public constructor
}


// Inflate the view for the fragment based on layout XML
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_attachment_tab, container, false);

    // get reference to the view elements
    addAtachments = view.findViewById(R.id.addAtachments);
    show_all_attachments_list = view.findViewById(R.id.show_all_attachments_list);


    // get the current user
    user = FirebaseAuth.getInstance().getCurrentUser();
    user_id = user.getUid();


    // get the expose id
    bundle = getArguments();
    immoID = bundle.getString("exposeID");

    // set the on ClickListener to the addAttachments Button
    addAtachments.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // change the fragment
            Fragment addAttachmentFragment = new AddAttachmentFragment();
            FragmentManager manager = getFragmentManager();
            newBundle = new Bundle();
            newBundle.putString("exposeID", immoID);
            addAttachmentFragment.setArguments(newBundle);
            manager.beginTransaction().replace(R.id.content_frame, addAttachmentFragment).addToBackStack(null).commit();

        }
    });

    // get reference to the database and storage
    immoDataRef = FirebaseDatabase.getInstance().getReference(Constants.DATABASE_PATH_IMMOBILIEN).child(user_id).child(immoID);
    pictureDataRef = FirebaseDatabase.getInstance().getReference(Constants.DATABASE_PATH_UPLOADS).child(user_id).child(immoID);
    contactDataRef = FirebaseDatabase.getInstance().getReference(Constants.DATABASE_PATH_CONTACTS).child(user_id).child(immoID);
    pictureStorageRef = FirebaseStorage.getInstance().getReference(user_id).child(Constants.STORAGE_PATH_UPLOADS);


    //return the view
    return view;
}

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    inflater.inflate(R.menu.showexposemenu, menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    final FragmentManager manager = getFragmentManager();
    // get the expose id
    bundle = getArguments();
    immoID = bundle.getString("exposeID");


    switch (item.getItemId()) {
        case R.id.edit_expose:
            Toast.makeText(getContext(), "Expose bearbeiten geklickt.", Toast.LENGTH_SHORT).show();

            // put the immoID into new Bundle
            newBundle = new Bundle();
            newBundle.putString("exposeID", immoID);
            // get a new instance of editExposeFragment
            Fragment editExpose = new EditExposeFragment();
            // set the newBundle as Arguments to the fragement
            editExpose.setArguments(newBundle);
            // switch the fragment
            manager.beginTransaction().replace(R.id.content_frame, editExpose).commit();

            break;
        case R.id.delete_expose:
            Toast.makeText(getContext(), "Expose wurde gelöscht.", Toast.LENGTH_SHORT).show();

            immoDataRef.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    immoDataRef.removeValue();
                    pictureDataRef.removeValue();
                    contactDataRef.removeValue();

                    Fragment showAllExpose = new ShowAllExposeFragment();
                    manager.beginTransaction().replace(R.id.content_frame, showAllExpose).commit();
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            });

            break;

    }
    return super.onOptionsItemSelected(item);
}

@Override
public void onStart() {
    super.onStart();
    // attaching the ValueEventListener
    pictureDataRef.addValueEventListener(new ValueEventListener() {


        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            // check if there are values in the database
            if (dataSnapshot.getValue() != null) {

                // clear the list of immos
                pictureUploads.clear();

                for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
                    // getting the immo
                    PictureUpload pictureUpload = postSnapshot.getValue(PictureUpload.class);
                    // adding the immo to the list
                    pictureUploads.add(pictureUpload);
                }

                // creating the List Adapter and add him to the Listview
                final AttachmentList attachmentAdapter = new AttachmentList((Activity) getContext(), pictureUploads);
                show_all_attachments_list.setAdapter(attachmentAdapter);


            }

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {


        }

    });


}
}

当我尝试在设备上运行我的应用时,我总是收到以下错误:

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.webgalaxie.blischke.bachelortakesix, PID: 14901
                  java.lang.NullPointerException: Attempt to invoke interface method 'void java.util.List.clear()' on a null object reference
                      at com.webgalaxie.blischke.bachelortakesix.fragments.tabfragments.AttachmentTabFragment$3.onDataChange(AttachmentTabFragment.java:191)
                      at com.google.android.gms.internal.zzegf.zza(Unknown Source)
                      at com.google.android.gms.internal.zzeia.zzbyc(Unknown Source)
                      at com.google.android.gms.internal.zzeig.run(Unknown Source)
                      at android.os.Handler.handleCallback(Handler.java:751)
                      at android.os.Handler.dispatchMessage(Handler.java:95)
                      at android.os.Looper.loop(Looper.java:154)
                      at android.app.ActivityThread.main(ActivityThread.java:6682)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)

有没有人知道为什么会这样。我有点卡在这个问题上。

非常感谢你的帮助。如果您需要有关该项目的更多信息,请不要犹豫。

如果您需要更多信息,我还可以在GitHub上获得该项目的代码。 链接到GitHub:https://github.com/BexxBl/BachelorTakeSix

1 个答案:

答案 0 :(得分:1)

这是因为在aws s3 cp {source_path} {s3_path} 方法中,您在尚未初始化的列表上调用onStart()。您应该初始化它而不是清除它:

clear()

编辑:快照的值是一个字符串。您还需要获取密钥并将其传递给 @Override public void onDataChange(DataSnapshot dataSnapshot) { // check if there are values in the database if (dataSnapshot.getValue() != null) { // clear the list of immos pictureUploads = new ArrayList(); for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) { // getting the immo PictureUpload pictureUpload = postSnapshot.getValue(PictureUpload.class); // adding the immo to the list pictureUploads.add(pictureUpload); } // creating the List Adapter and add him to the Listview final AttachmentList attachmentAdapter = new AttachmentList((Activity) getContext(), pictureUploads); show_all_attachments_list.setAdapter(attachmentAdapter); } } 课程。

PictureUpload