본문 바로가기
Project/안드로이드 프로젝트(ShareHouse)

Android Studio, JAVA] 구글 파이어베이스 데이터베이스와 리사이클러 뷰 이용 시 리사이클러 뷰가 뜨지 않는 현상 해결

by 김마리님 2020. 8. 14.

FAQ를 위해 구글 파이어베이스 데이터베이스 이용 중에 정보는 제대로 파싱해오는데, 정작 리사이클러 뷰가 뜨지 않는 현상과 마주했다.

(ㅇㄴ)

이 당시의 코드

 

- 리사이클러가 뜰 뷰 코드

package com.mary.sharehouseproject.fragment;

import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.firestore.QuerySnapshot;
import com.mary.sharehouseproject.R;
import com.mary.sharehouseproject.adapter.FaqRecyclerAdapter;
import com.mary.sharehouseproject.model.Faq;

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


public class FaqViewPager1 extends Fragment {
    private static final String TAG = "FaqViewPager1";

    private FaqRecyclerAdapter recyclerAdapter;
    private RecyclerView rcFaq;
    private List<Faq> faqList=new ArrayList<>();


    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v=inflater.inflate(R.layout.f_a_q_viewpage1,container,false);

        init(v);
        initData();
        Log.d(TAG, "onCreateView: 아니 여긴 오긴 해?");
        RecyclerView.LayoutManager layoutManager=new LinearLayoutManager(v.getContext());
        rcFaq.setLayoutManager(layoutManager);
        recyclerAdapter.notifyDataSetChanged();
        rcFaq.setAdapter(recyclerAdapter);

        return v;
    }

    private void initData(){
        FirebaseFirestore db = FirebaseFirestore.getInstance();
        db.collection("FAQ")
                .get()
                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<QuerySnapshot> task) {
                        if(task.isSuccessful()){
                            for(QueryDocumentSnapshot document : task.getResult()){
                                faqList.add(document.toObject(Faq.class));
                            }
                            Log.d(TAG, "onComplete: 데이터 반영 완료"+faqList);
                            recyclerAdapter.addFaqList(faqList);
                        }else{
                            Log.d(TAG, "onComplete: 실패");
                        }

                    }
                }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.d(TAG, "onFailure: "+e.getMessage());
            }
        });
    }

    private void init(View v){
        rcFaq=v.findViewById(R.id.rc_faq);
        recyclerAdapter=new FaqRecyclerAdapter();

    }
}

 

- 어댑터 코드

package com.mary.sharehouseproject.adapter;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

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

import com.mary.sharehouseproject.R;
import com.mary.sharehouseproject.model.Faq;

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

public class FaqRecyclerAdapter extends RecyclerView.Adapter<FaqRecyclerAdapter.FaqViewHolder> {
    private static final String TAG = "FaqRecyclerAdapter";

    List<Faq> faqLists = new ArrayList<>();

    public void addFaqList(Faq faq) {
        faqLists.add(faq);
    }

    public void addFaqList(List<Faq> faqLists) {
        this.faqLists = faqLists;
        Log.d(TAG, "addFaqList: add 확인: "+faqLists);
    }


    @NonNull
    @Override
    public FaqViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        Log.d(TAG, "onCreateViewHolder: 바인딩은 되니?");
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        View v = layoutInflater.inflate(R.layout.faq_item, parent, false);
        return new FaqViewHolder(v);
    }

    @Override
    public void onBindViewHolder(@NonNull FaqViewHolder holder, int position) {
        Faq faq = faqLists.get(position);
        Log.d(TAG, "onBindViewHolder: "+faq);
        holder.setItem(faq);
    }

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

    public static class FaqViewHolder extends RecyclerView.ViewHolder {

        private TextView tvFaqTitle, tvFaqContent;

        public FaqViewHolder(@NonNull final View itemView) {

            super(itemView);
            Log.d(TAG, "FaqViewHolder: ????????????");

            tvFaqTitle = itemView.findViewById(R.id.tv_faq_title);
            tvFaqContent = itemView.findViewById(R.id.tv_faq_content);
            tvFaqContent.setVisibility(View.GONE);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    tvFaqContent.setVisibility(View.VISIBLE);
                }
            });
        }

        public void setItem(Faq faq) {
            tvFaqTitle.setText(faq.getTitle());
            tvFaqContent.setText(faq.getContent());
        }
    }
}

 

 

코드 자체만 보면 진짜 멀쩡해보여서, 한동안 못찾다가 하나하나 로그를 찍어보기에 이르는데..

디버그 로그 :

보면 리사이클러 뷰가 뜨는 것 보다 데이터 바인딩이 늦어서 생기는 현상이었다 ㅜㅜ

그렇다보니 리사이클러 뷰는 빈 뷰를 가지게 되고, 이후에 바인딩이 되는데, 파이어베이스로 데이터를 가져오는 것이 다른 스레드여서 생기는 현상 같았다.

그래서, 메인 뷰의 코드를, task 호출에 성공했을 때 뷰를 호출하도록 코드를 수정했다.

package com.mary.sharehouseproject.fragment;

import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.firestore.QuerySnapshot;
import com.mary.sharehouseproject.R;
import com.mary.sharehouseproject.adapter.FaqRecyclerAdapter;
import com.mary.sharehouseproject.model.Faq;

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


public class FaqViewPager1 extends Fragment {
    private static final String TAG = "FaqViewPager1";

    private FaqRecyclerAdapter recyclerAdapter;
    private RecyclerView rcFaq;
    private List<Faq> faqList=new ArrayList<>();


    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v=inflater.inflate(R.layout.f_a_q_viewpage1,container,false);

        init(v);
        initData();
        Log.d(TAG, "onCreateView: 아니 여긴 오긴 해?");
        return v;
    }

    private void initData(){
        FirebaseFirestore db = FirebaseFirestore.getInstance();
        db.collection("FAQ")
                .get()
                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<QuerySnapshot> task) {
                        if(task.isSuccessful()){
                            for(QueryDocumentSnapshot document : task.getResult()){
                                faqList.add(document.toObject(Faq.class));
                            }
                            Log.d(TAG, "onComplete: 데이터 반영 완료"+faqList);
                            RecyclerView.LayoutManager layoutManager=new LinearLayoutManager(getContext());
                            recyclerAdapter.addFaqList(faqList);
                            rcFaq.setLayoutManager(layoutManager);
                            recyclerAdapter.notifyDataSetChanged();
                            rcFaq.setAdapter(recyclerAdapter);
                        }else{
                            Log.d(TAG, "onComplete: 실패");
                        }

                    }
                }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.d(TAG, "onFailure: "+e.getMessage());
            }
        });
    }

    private void init(View v){
        rcFaq=v.findViewById(R.id.rc_faq);
        recyclerAdapter=new FaqRecyclerAdapter();

    }
}

 

 

다만 이렇게 하면 기기에 따라 로드 되는 속도가 달라서.. 이후에 로딩 중 화면을 구현하던가 해야할 것 같다.

반응형