java - Android Firebase - 卡未在 RecyclerView 和 NullPointerException 中显示

标签 java android firebase android-recyclerview

我正在尝试构建一个应用程序,用户可以在其中发布带有图像和描述的内容,这些内容单独包含在 CardView 中的 RecyclerView 中。所以我遇到了三个问题

1.当id(userId)用作子项,然后我发布数据时,它会被旧数据替换,而不是添加新数据(如果帖子有多个具有相同ID的子项,那么我的卡片应该显示,但ID每次都会被替换时间)

  • 添加帖子时卡片不会显示。(当帖子中有帖子时 Firebase 数据库)
  • 如果默认情况下 Firebase 数据库中没有帖子 NullPointerException 到方法 getDesc() 甚至生成 尽管我已经进行了空检查。
  • 之前,为了存储帖子,我使用的子项是 id(userId) ,但帖子被替换而不是添加新帖子,因此我使用了随机字符串生成器并尝试从中获取信息。

    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>
    
    

    enter image description here

    最佳答案

    要修复 NullPointerException,请检查 postItems.get(position) 的 null 值,而不是 postItems.get(position).getDesc() ,即

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

    此外,您正在使用空白的 postItems 列表初始化 PostAdapter,即

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

    项目随后添加到 ValueEventListener 的 onDataChange() 方法中。您必须为新更新的 List postItems 更新 PostAdapter 并通知适配器。像这样。

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

    对于未显示的卡片,您可以分享 post_items.xml 文件的代码吗?

    关于java - Android Firebase - 卡未在 RecyclerView 和 NullPointerException 中显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56680332/

    相关文章:

    Java - 检查字符串中的最后一个字符是否为数字

    android - AlertDialog ONClickListener 不工作

    java - 如何将 fragment 添加到没有 ID 的 View 中?

    javascript - Firebase Auth Multifactor - 用户对象不返回 multiFactor 属性

    android - 等待 Firebase 异步在 Android 中检索数据

    java - 如何在 Java 代码中调用 bash cmd "find -L"

    java - maven从错误的存储库下载

    java - 使用 View 模型将数据从 Activity 发送到 fragment

    android - 谷歌播放显示我所有的截图

    android - Firebase 函数困惑 : Which database?