@SimpleName

Как исправить проблему при загрузке данных из Firebase database в RecyclerView фрагмента?

В фрагменте есть RecyclerView, в который должны загружаться картинки. Оданко при тесте приложение вылетает при переходе на фрагмент с этим RecyclerView. Как это можно исправить?
Вот структура данных в Firebase database
5c48ac30e8a50797216173.png
код фрагмента с RecyclerView
public class TestFragment extends Fragment {

    private ArrayList<GalleryGridObject> galleryList = new ArrayList<GalleryGridObject>();
    private TestAdapter mAdapter;
    private RecyclerView recyclerView;
    private DatabaseReference mDatabase;

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


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


        recyclerView = view.findViewById(R.id.my_recycler_view);

        LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.hasFixedSize();
        mDatabase = FirebaseDatabase.getInstance().getReference("Data");
        mDatabase.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
                for (DataSnapshot ds : dataSnapshot.getChildren()) {
                    System.out.println(ds.getValue());
                    GalleryGridObject doc = ds.getValue(GalleryGridObject.class);

                    galleryList.add(doc);

                    mAdapter = new TestAdapter(galleryList);
                    recyclerView.setAdapter(mAdapter);
                }

                mAdapter = new TestAdapter(galleryList);
                recyclerView.setAdapter(mAdapter);
            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) { }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) { }

            @Override
            public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) { }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
                Log.w("LogFragment", "loadLog:onCancelled", databaseError.toException());
            }
        });

        return view;
    }

}

адаптер RecyclerView
public class TestAdapter extends RecyclerView.Adapter<TestAdapter.ViewHolder> {

    private TestFragment mContext;
    private ArrayList<GalleryGridObject> galleryArrayList;

    public TestAdapter(ArrayList<GalleryGridObject> galleryArrayList){
        //this.mContext=mContext;
        this.galleryArrayList=galleryArrayList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_coupons, parent, false);

        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        GalleryGridObject gallery = galleryArrayList.get(position);
        Glide.with(mContext).load(gallery.getCompanyImage()).into(holder.imageGallery);
    }

    @Override
    public int getItemCount() {
        if(galleryArrayList==null) return 0;
        return galleryArrayList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        public ImageView imageGallery;

        public ViewHolder(View view) {
            super(view);
            imageGallery = itemView.findViewById(R.id.coupons_picture);
        }
    }
}

модель для RecyclerView
public class GalleryGridObject {

    String companyImage;

    public GalleryGridObject () {}

    public GalleryGridObject(String companyImage) {
        this.companyImage = companyImage;
    }

    public String getCompanyImage() {
        return companyImage;
    }

    public void setGalleryImage(String galleryImage) {
        this.companyImage = galleryImage;
    }
}

Logcat
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type com.example.asus.socialmap.GalleryGridObject
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(com.google.firebase:firebase-database@@16.0.5:423)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(com.google.firebase:firebase-database@@16.0.5:214)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(com.google.firebase:firebase-database@@16.0.5:79)
        at com.google.firebase.database.DataSnapshot.getValue(com.google.firebase:firebase-database@@16.0.5:212)
        at com.example.asus.socialmap.TestFragment$1.onChildAdded(TestFragment.java:65)
        at com.google.firebase.database.core.ChildEventRegistration.fireEvent(com.google.firebase:firebase-database@@16.0.5:79)
        at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database@@16.0.5:63)
        at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database@@16.0.5:55)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6798)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

  • Вопрос задан
  • 311 просмотров
Решения вопроса 1
@SimpleName Автор вопроса
Надо изменить
private ArrayList<GalleryGridObject> galleryList = new ArrayList<>();
на private List<GalleryGridObject> galleryList; В итоге код фрагмента (или активити) должен получиться так
В итоге код фрагмента (или активити) должен получиться так
public class TestFragment extends Fragment {

private List<GalleryGridObject> galleryList;
private TestAdapter mAdapter;
private RecyclerView recyclerView;
private DatabaseReference mRef;
private FirebaseDatabase database;

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


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

    recyclerView = view.findViewById(R.id.my_recycler_view);
    recyclerView.setHasFixedSize(true);
    LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
    layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
    recyclerView.setLayoutManager(layoutManager);
    galleryList = new ArrayList<>();

    mAdapter = new TestAdapter(galleryList);

    database = FirebaseDatabase.getInstance();
    //mRef = database.getReference().child("Data");
    mRef = database.getReference("Data");

    mRef.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
            GalleryGridObject image = dataSnapshot.getValue(GalleryGridObject.class);
            galleryList.add(image);
            recyclerView.setAdapter(mAdapter);
        }

        @Override
        public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

        }

        @Override
        public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {

        }

        @Override
        public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

        }

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

        }
    });

    return view;
}

public class TestAdapter extends RecyclerView.Adapter<TestAdapter.ViewHolder>{
    private Context mContext;
    private List<GalleryGridObject> galleryArrayList;

    public TestAdapter( List<GalleryGridObject> galleryArrayList){
        //this.mContext=mContext;
        this.galleryArrayList=galleryArrayList;
    }

    @NonNull
    @Override
    public TestAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_coupons, parent, false);

        return new TestAdapter.ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull TestAdapter.ViewHolder holder, int position) {
        //GalleryGridObject gallery = galleryArrayList.get(position);
        //Glide.with(mContext).load(galleryArrayList.get(position).getImage()).into(holder.imageGallery);
        holder.textView.setText(galleryArrayList.get(position).getTitle());
        Picasso.get().load(galleryArrayList.get(position).getImage()).into(holder.imageGallery);
    }

    @Override
    public int getItemCount() {
        if(galleryArrayList==null) return 0;
        return galleryArrayList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        public ImageView imageGallery;
        public TextView textView;

        public ViewHolder(View view) {
            super(view);
            imageGallery = itemView.findViewById(R.id.coupons_picture);
            textView = itemView.findViewById(R.id.coupons_title);
        }
    }
}

}

Вот модель для RecyclerView (обязательно нужен пустой конструктор)
@IgnoreExtraProperties
public class GalleryGridObject {

String title, image;

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

public GalleryGridObject(String title, String image) {
    this.title = title;
    this.image = image;
}

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

public String getImage() {
    return image;
}

public void setImage(String image) {
    this.image = image;
}
}


Единственное, что я так и не понял, это почему картинки не должны лежать сразу в родительской папке (в моем случае Data, которую указываем в mRef = database.getReference("Data");), а должны иметь собственные папки, на подобии этого (тут вместо папки "Data" показана папка "KFC", но суть не меняется
5c4d8fa39f25c136376594.png
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
zagayevskiy
@zagayevskiy Куратор тега Android
Android developer at Yandex
Очевидно, что в фаербэйзе у тебя стринги лежат, а читать ты пытаешься свой объект.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы