简体   繁体   中英

Android Firebase -Cards not displaying in RecyclerView and NullPointerException

I am trying to build an app where users can post something with image and description which is included individually in CardView in RecyclerView . So I have have got three problems

1.When id(userId) is used as child and then I post the data it gets replaced with old data instead of adding new data (if the posts has multiple children with same ID then my cards should display but the ID is getting replaced every time)

  1. Cards aren't showing when a post is added.(When there are posts in Firebase database)
  2. If by default there are no posts in Firebase database NullPointerException to the method getDesc() is generated even though I have put null checks.

Earlier for storing posts the child I used was id(userId) , but the posts got replaced instead of adding a new one so I used a random String generator and tried to fetch information from it instead.

HomeFragment.java


    public class HomeFragment extends Fragment {

    private RecyclerView rv;
    private TextView username,date,desc;
    private CircleImageView postImage;
    private ImageView postBigImage;
    private CardView postCard;
    private List<PostActivity> postItems;
    private DatabaseReference dr;
    private StorageReference sr;
    private FirebaseUser user;
    //FirebaseRecyclerAdapter<PostActivity, userViewHolder> fra;


    private PostAdapter pa;

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



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


        sr = FirebaseStorage.getInstance().getReference();
        user = FirebaseAuth.getInstance().getCurrentUser();
        String id = user.getUid();

        AddPost ap = new AddPost();

        dr = 
      FirebaseDatabase.getInstance().getReference().child("Posts")
      .child(ap.getUni());

        postItems = new ArrayList<>();
        pa = new PostAdapter(postItems);

        rv =view.findViewById(R.id.rvPostItems);

        rv.setLayoutManager(new LinearLayoutManager(getActivity()));

        rv.setAdapter(pa);



        dr.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                for (DataSnapshot ds : dataSnapshot.getChildren()){

                    //postItems.add(ds.getValue(PostActivity.class));

                    PostActivity pa =dataSnapshot.getValue(PostActivity.class);
                    postItems.add(pa);

                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

        return view;
    }


    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);
    }
}

PostAdapter.java

package com.pappu5.navigation;

import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.List;

public class PostAdapter extends RecyclerView.Adapter<PostAdapter.ViewHolder> {

    public List<PostActivity> postItems;

    public PostAdapter(List<PostActivity> postItems) {
        this.postItems = postItems;

    }

    @NonNull
    @Override
    public PostAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.post_items,parent,false);

        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final PostAdapter.ViewHolder holder, int position) {
        String descTe = postItems.get(position).getDesc();
        if(descTe!=null) {

            holder.setDesc(descTe);
        }else{
            String def = "This is NULL";
            holder.setDesc(def);
        }
    }

    @Override
    public int getItemCount() {


        return postItems.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder{

        private TextView desc;
        private View mView;

        public ViewHolder(View itemView) {
            super(itemView);
            mView = itemView;
        }

        public void setDesc(String descText){
            desc = mView.findViewById(R.id.postDesc);

                desc.setText(descText);

        }
    }

}


AddPost.java

package com.pappu5.navigation;

public class AddPost extends AppCompatActivity {

    private Toolbar toolbar;
    private ImageView postImage;
    private Button postButton;
    private EditText postDesc;
    private static final int gallery_no = 1;
    private ProgressDialog pd;
    private FirebaseUser user;
    private StorageReference sr;
    private DatabaseReference dr;
    private Uri postImageUri = null;
    private Bitmap compressor;
    String date = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(new Date());



    protected String getSaltString() {
        String SALTCHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
        StringBuilder salt = new StringBuilder();
        Random rnd = new Random();
        while (salt.length() < 18) { // length of the random string.
            int index = (int) (rnd.nextFloat() * SALTCHARS.length());
            salt.append(SALTCHARS.charAt(index));
        }
        String saltStr = salt.toString();
        return saltStr;

    }

    String uni = getSaltString();

    public String getUni(){
        return this.uni;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_post);

        toolbar = findViewById(R.id.postBar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setTitle("Add New Post !");

        postImage = findViewById(R.id.postImage);
        postDesc = findViewById(R.id.inputDesc);
        postButton = findViewById(R.id.post);

        sr = FirebaseStorage.getInstance().getReference();
        user = FirebaseAuth.getInstance().getCurrentUser();

        String id = user.getUid();


        dr = FirebaseDatabase.getInstance().getReference().child("Posts").child(uni);
        dr.keepSynced(true);


        postImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent gallery = new Intent();
                gallery.setType("image/*");
                gallery.setAction(Intent.ACTION_GET_CONTENT);

                startActivityForResult(Intent.createChooser(gallery,"Select Image"),gallery_no);
            }
        });

        postButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                String desc = postDesc.getText().toString();

                if(!TextUtils.isEmpty(desc) && postImageUri!=null ){
                    pd = new ProgressDialog(AddPost.this);
                    pd.setTitle("Uploading..");
                    pd.setMessage("Please Wait ..");
                    pd.setCanceledOnTouchOutside(false);
                    pd.show();

                    final String id = user.getUid();


                    File thumb = new File(postImageUri.getPath());
                    try {
                        compressor = new Compressor(AddPost.this)
                                .setMaxWidth(200)
                                .setMaxHeight(200)
                                .setQuality(75)
                                .compressToBitmap(thumb);




                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    compressor.compress(Bitmap.CompressFormat.JPEG, 100, baos);

                    final byte[] thumb_byte = baos.toByteArray();



                    final StorageReference path = sr.child("Post_Images").child(id + ".jpg");

                    final StorageReference thumb_nail = sr.child("Post_Images").child("Thumb_Nails").child(id+".jpg");

                    path.putFile(postImageUri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
                        @Override
                        public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
                            if (task.isSuccessful()) {

                                path.putFile(postImageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                                    @Override
                                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                                        path.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                                            @Override
                                            public void onSuccess(Uri uri) {
                                                final String down_url = uri.toString();

                                                UploadTask uploadTask = thumb_nail.putBytes(thumb_byte);
                                                uploadTask.addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
                                                    @Override
                                                    public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {

                                                        thumb_nail.putFile(postImageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                                                            @Override
                                                            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                                                                thumb_nail.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                                                                    @Override
                                                                    public void onSuccess(Uri uri) {


                                                                        final String thumb_down_url = uri.toString();

                                                                        Map <String,Object> update_map = new HashMap<>();
                                                                        update_map.put("image", down_url);
                                                                        update_map.put("thumb_image", thumb_down_url);
                                                                        update_map.put("desc",desc);

                                                                        update_map.put("timestamp", date);

                                                                        dr.updateChildren(update_map).addOnCompleteListener(new OnCompleteListener<Void>() {
                                                                            @Override
                                                                            public void onComplete(@NonNull Task<Void> task) {
                                                                                if (task.isSuccessful()) {
                                                                                    Toast.makeText(AddPost.this, "Uploaded !", Toast.LENGTH_SHORT).show();
                                                                                    Intent intent = new Intent(AddPost.this,MainActivity.class);
                                                                                    startActivity(intent);
                                                                                    finish();

                                                                                    pd.dismiss();
                                                                                } else {
                                                                                    Toast.makeText(AddPost.this, "Error in uploading thumbnail!", Toast.LENGTH_SHORT).show();
                                                                                    pd.dismiss();
                                                                                }
                                                                            }
                                                                        });



                                                                    }
                                                                });
                                                            }
                                                        });
                                                    }
                                                });

                                            }
                                        });
                                    }
                                });

                            } else {
                                Toast.makeText(AddPost.this, "Error!", Toast.LENGTH_SHORT).show();
                                pd.dismiss();
                            }
                        }
                    });


                }
            }
        });

    }


    public void onActivityResult(int requestCode, int resultCode, Intent data) {

        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == gallery_no && resultCode == RESULT_OK) {
            Uri imageUri = data.getData();

            CropImage.activity(imageUri).setAspectRatio(1, 1).setMinCropWindowSize(500, 500)
                    .start(AddPost.this);
        }


        if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {

            CropImage.ActivityResult result = CropImage.getActivityResult(data);

            if (resultCode == RESULT_OK) {


                postImageUri = result.getUri();
                postImage.setImageURI(postImageUri);



            } else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) {
                Exception error = result.getError();
            }
        }
    }

}


post_items.xml


<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <android.support.v7.widget.CardView
        android:id="@+id/postCard"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.56"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <de.hdodenhof.circleimageview.CircleImageView
                android:id="@+id/postImage"
                android:layout_width="65dp"
                android:layout_height="65dp"
                android:layout_marginStart="16dp"
                android:layout_marginTop="16dp"
                android:src="@drawable/default_avatar"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/postUsername"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="16dp"
                android:layout_marginTop="16dp"
                android:text="Username"
                android:textStyle="bold"
                app:layout_constraintStart_toEndOf="@+id/postImage"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/postDate"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="16dp"
                android:text="Datee"
                android:textStyle="italic"
                app:layout_constraintStart_toEndOf="@+id/postImage"
                app:layout_constraintTop_toBottomOf="@+id/postUsername" />

            <ImageView
                android:id="@+id/postBigImage"
                android:layout_width="0dp"
                android:layout_height="256dp"
                android:scaleType="centerCrop"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/postImage"
                tools:srcCompat="@tools:sample/avatars[3]" />

            <TextView
                android:id="@+id/postDesc"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="16dp"
                android:layout_marginTop="16dp"
                android:layout_marginEnd="16dp"
                android:layout_marginBottom="16dp"
                android:text="TextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextView"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/postBigImage" />
        </android.support.constraint.ConstraintLayout>

    </android.support.v7.widget.CardView>


</android.support.constraint.ConstraintLayout>

在此处输入图片说明

To fix NullPointerException check null value of postItems.get(position) instead of postItems.get(position).getDesc() ie

@Override
public void onBindViewHolder(@NonNull final PostAdapter.ViewHolder holder, int position) {
    if(postItems.get(position) != null) {
        String descTe = postItems.get(position).getDesc();

        holder.setDesc(descTe);
    } else {
        String def = "This is NULL";
        holder.setDesc(def);
    }
}

Also, you are initializing PostAdapter with blank List of postItems, ie

postItems = new ArrayList<>();
pa = new PostAdapter(postItems);

and Items are added later inSide onDataChange() method of the ValueEventListener. you must update your PostAdapter for the new updated List postItems and notify the adapter. like this.

public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            for (DataSnapshot ds : dataSnapshot.getChildren()){

                //postItems.add(ds.getValue(PostActivity.class));

                PostActivity pa =dataSnapshot.getValue(PostActivity.class);
                postItems.add(pa);

            }
            pa.notifyDataSetChanged();
        }

And for Cards not being displayed can you share the code of post_items.xml file.

(Posted an answer on behalf of the question author).

I solved every problem by removing whole PostAdapter class and then implementing FireebaseRecyclerAdapter in the HomeFragment itself ! My cards are displaying like charm now ! Thanks to everyone who replied to me here and helped me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM