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)
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.