简体   繁体   中英

Recycler View items not showing

I have a RecyclerView on my homepage when getting some data from Firebase Realtime Database and then create views with this data, but when I run my app I get some error messages on the log cat and the items on my homepage are not displayed. I have tried everything but nothing is working.

Also i get this on the log:

D/GGGGGGG: value is (name of user 1)
D/GGGGGGG: value is (name of user 2)

post_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:padding="15dp"
    app:cardCornerRadius="20dp"
    android:layout_gravity="center_horizontal"
    app:cardElevation="20dp"
    android:outlineSpotShadowColor="@color/teal_200">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/post_username"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="start"
            android:layout_marginStart="10dp"
            android:layout_marginTop="5dp"
            android:clickable="true"
            android:focusable="true"
            android:text="By george sepetadelis"
            android:textColor="@color/black"
            android:textSize="17sp"
            android:textStyle="bold"
            app:layout_constraintBottom_toTopOf="@+id/post_image"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="1.0" />

        <ImageView
            android:id="@+id/post_image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginTop="10dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/post_username"
            app:srcCompat="@drawable/m1" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

PostModel.java:

package com.sm.socialmeme;

public class PostModel {
    String name;
    String imgUrl;

    // constractors \\
    public PostModel(String name, String imgUrl) {
        this.name = name;
        this.imgUrl = imgUrl;
    }

    public PostModel(){

    }

    // getters and setters \\
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getImgUrl() {
        return imgUrl;
    }

    public void setImgUrl(String imgUrl) {
        this.imgUrl = imgUrl;
    }
}

My database: `![在此处输入图片描述](https://i.stack.imgur.com/uLvIn.jpg)

Errors on the log cat:

2021-01-10 18:43:39.976 28203-28203/? E/m.sm.socialmem: Unknown bits set in runtime_flags: 0x28000
2021-01-10 18:43:47.168 28203-28706/com.sm.socialmeme E/Perf: Fail to get file list com.sm.socialmeme
2021-01-10 18:43:47.171 28203-28706/com.sm.socialmeme E/Perf: getFolderSize() : Exception_1 = java.lang.NullPointerException: Attempt to get length of null array
2021-01-10 18:43:51.508 28203-28203/com.sm.socialmeme E/RecyclerView: No adapter attached; skipping layout

RecyclerAdapter.java:

package com.sm.socialmeme;

import android.content.Context;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;

import org.jetbrains.annotations.NotNull;

import java.util.List;

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

    List<PostModel> postList;
    Context context;

    public RecyclerAdapter(Context context,List<PostModel> postList) {
        this.postList = postList;
        this.context = context;
    }

    @NonNull
    @NotNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.post_item,parent,false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull @NotNull ViewHolder holder, int position) {
        //PostModel postModel = postList.get(position);
        // set username \\
        holder.username.setText(postList.get(position).getName());
        // set image URL \\
        Glide.with(context).load(postList.get(position).getImgUrl()).into(holder.postImg);
    }

    @Override
    public int getItemCount() {
        return postList.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder{
        TextView username;
        ImageView postImg;

        public ViewHolder(@NonNull @NotNull View itemView) {
            super(itemView);
            username = itemView.findViewById(R.id.post_username);
            postImg = itemView.findViewById(R.id.post_image);
        }
    }
}

HomeActivity.java:

package com.sm.socialmeme;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.content.ContentResolver;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.webkit.MimeTypeMap;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
import com.google.firebase.database.ValueEventListener;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;

public class HomeActivity extends AppCompatActivity {

    // global variables \\
    DatabaseReference mRef;
    List<PostModel> postList;
    RecyclerView.Adapter recyclerAdapter;
    RecyclerView recyclerView;
    ProgressBar progressBar;

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

        final FirebaseAuth mAuth = FirebaseAuth.getInstance();
        final FirebaseUser user = mAuth.getCurrentUser();
        final ImageButton new_post = findViewById(R.id.new_post_btn);
        final ImageButton settings = findViewById(R.id.settingsButton);
        recyclerView = findViewById(R.id.recyclerView);
        mRef = FirebaseDatabase.getInstance().getReference().child("posts");
        progressBar = findViewById(R.id.progressBar4);
        progressBar.setVisibility(View.VISIBLE);
        postList = new ArrayList<>();
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        if (user == null) {
            finish();
            startActivity(new Intent(HomeActivity.this, MainActivity.class));
        }

            mRef.addValueEventListener(new ValueEventListener(){
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot){
                    clearList();
                    for (DataSnapshot snapshot : dataSnapshot.getChildren()){
                        PostModel post = new PostModel();
                        post.setImgUrl(snapshot.child("imgUrl").getValue().toString());
                        post.setName(snapshot.child("name").getValue().toString());
                        postList.add(post);

                        // debug code \\
                        // note: the data from the db is coming correct
                        String value = snapshot.child("imgUrl").getValue().toString();
                        Log.d("GGGGGGGGG","Value is: " + value);
                    }
                    progressBar.setVisibility(View.GONE);
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError){
                    Toast.makeText(HomeActivity.this, "Error: " + databaseError, Toast.LENGTH_SHORT).show();
                    progressBar.setVisibility(View.GONE);
                }
            });

            recyclerAdapter = new RecyclerAdapter(HomeActivity.this,postList);
            recyclerView.setAdapter(recyclerAdapter);
            recyclerAdapter.notifyDataSetChanged();


        settings.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(HomeActivity.this, SettingsActivity.class));
            }
        });

        new_post.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(HomeActivity.this, UploadPhotoActivity.class));
            }
        });
    }

    public void clearList(){
        if (postList != null){
            postList.clear();
            if (recyclerAdapter != null){
                recyclerAdapter.notifyDataSetChanged();
            }
        }
        postList = new ArrayList<>();
    }
}

When you create a new instance of your adapter class and you pass a List<PostModel> objects to its constructor, it means that you want to create a view for each and every object that exists within that location. Seeing your screenshot, I can tell you for sure that under the "posts" node, there are no objects of type "PostModel", there are only String objects. To solve this, when you add data, make sure to have a schema similar to this:

Firebase-root
  |
  --- posts
       |
       --- postId
       |    |
       |    --- name: "Nice Image"
       |    |
       |    --- imgUrl: "https://..."
       |
       --- postId
            |
            --- name: "Very Nice Image"
            |
            --- imgUrl: "https://..."

Now, under the "posts" node you can see two "PostModel" objects. Now, you can attach a listener on this node, get the data as a List<PostModel> , pass this list to the adapter and the problem should be solved.

Try with

postList.add(post);
//then
if (recyclerAdapter != null){
     recyclerAdapter.notifyDataSetChanged();
}

You are adding an item to the list, but you are not notifying the adapter that an item has been added

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