마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

안드로이드 Activity Recyclerview 질문

0 추천

안드로이드 Fragment가 아닌 Activity에서 버튼 클릭 시 Firebase에서 데이터를 받아서 Recylcerview item에 넣고 싶은데 아무것도 뜨질 않습니다..
어떻게 해야하나요..?

현재 코드는 이렇습니다..

private RecyclerView recyclerView;
private FirestoreAdapter firestoreAdapter;
public StorageReference storageReference;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate( savedInstanceState );
    setContentView( R.layout.activity_main );
    recyclerView = findViewById( R.id.main_recyclerview );
    recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
}
@Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.search:
                firestoreAdapter = new RecyclerViewAdapter( FirebaseFirestore.getInstance().collection( "컬렉션ID" ).orderBy("day", Query.Direction.ASCENDING));
                recyclerView.setAdapter(firestoreAdapter);
                firestoreAdapter.notifyDataSetChanged();
                break;
        }
    }
    public class RecyclerViewAdapter extends FirestoreAdapter<CustomViewHolder> {
        RecyclerViewAdapter(Query query) {
            super( query );
            storageReference = FirebaseStorage.getInstance().getReference();
        }
        @Override
        public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            return new CustomViewHolder( LayoutInflater.from( parent.getContext() )
                    .inflate( R.layout.recyclerview_item, parent, false ) );
        }
        @Override
        public void onBindViewHolder(final CustomViewHolder viewHolder, final int position) {
            DocumentSnapshot documentSnapshot = getSnapshot( position );
            final Model model = documentSnapshot.toObject( Model.class );
           
                viewHolder.id.setText(model.getId());
               
                    public void onClick(View v) {
                        

                });
            }
        }
    }
꿀개 (2,440 포인트) 님이 2020년 11월 15일 질문

2개의 답변

0 추천
Activity에서 search 버튼 누르면 값에 따라 각각 다른 데이터를 Recyclerview에 표현하고 싶습니다..
꿀개 (2,440 포인트) 님이 2020년 11월 15일 답변
0 추천

RecyclerView는  onCreate에서 초기화하세요.

firestoreAdapter = new RecyclerViewAdapter();
recyclerView.setAdapter(firestoreAdapter);

RecyclerView adapter는 ListAdapter를 사용하세요. 리스트가 많아질 수록 변경된 아이템을 최적화된 코드로 비교해 주기 때문에 성능이 개선될 수 있습니다.
 

class FireStoreAdapter extends ListAdapter< FireStoreItem, CustomViewHolder > {
     public UserAdapter() {
         super(User.DIFF_CALLBACK);
     }
     @Override
     public void onBindViewHolder(CustomViewHolder holder, int position) {
         holder.bindTo(getItem(position));
     }
     public static final DiffUtil.ItemCallback< FireStoreItem > DIFF_CALLBACK =
             new DiffUtil.ItemCallback<User>() {
         @Override
         public boolean areItemsTheSame(
                 @NonNull FireStoreItem oldItem, @NonNull FireStoreItem newItem) {
             // User properties may have changed if reloaded from the DB, but ID is fixed
             return oldItem.getId() == newItem.getId();
         }
         @Override
         public boolean areContentsTheSame(
                 @NonNull FireStoreItem oldItem, @NonNull FireStoreItem newItem) {
             // NOTE: if you use equals, your object must properly override Object#equals()
             // Incorrectly returning false here will result in too many animations.
             return oldItem.equals(newItem);
         }
     }
 }

Firebase의  snapshot의 adapter에 다 넘기지 마시고 adapter가 바로 화면에 그릴 수 있는 쉬운 클래스로 맵핑하여 넘기세요.

public class FireStoreItem {
    private final int layoutId;
    private final Model model;

    public Model(int layoutId, Model model) {
        this.layoutId = layoutId;
        this.model = model;
    }

    public int getLayoutId() {
        return layoutId;
    }

    public String getId() {
        return id;
    }
}

private List<FireStoreItem> getFireStoreData() {
   // Firestore에서 데이터를 가져오는 부분은 백그라운드에서 수행하기를 권장합니다.
   DocumentSnapshot document = FirebaseFirestore.getInstance()
       .collection( "컬렉션ID" )
       .orderBy("day", Query.Direction.ASCENDING));
   // 여기서 객체 변환
  
   return FireStoreUtil.mapToModels(document);

}

firestoreAdapter.submitList(getFireStoreData());

class FireStoreUtil {
    public static List<FireStoreItem> mapToModels(DocumentSnapshot document )
       List<FireStoreItem> result = new ArrayList<>();
       final Model model = documentSnapshot.toObject(Model.class);
       result.add(new FireStoreItem(R.layout.item_list1, model));
       return result;
   }
}
           

RecyclerView adpater를 FirebaseItem의 layoutId에 따라서 처리.

class FireStoreAdapter extends ListAdapter< FireStoreItem, CustomViewHolder > {
     @Override
     public int getViewType(int position) {
         return getItem(position).getLayoutId();
     }
    
     @Override
     public CustomViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        int layoutId = viewType;
        View view = LayoutInflater.from(viewGroup.getContext())
                .inflate(layoutId, viewGroup, false);

        switch (layoutId) {
             case R.layout.item_list1: return new ViewHolder1(view);
             case R.layout.item_list2: return new ViewHolder2(view);
             case R.layout.item_list3: return new ViewHolder3(view);
            default: throw new IllegalArgumentException("Cannot find view type: " + viewType);
        }
        
    }
  
     @Override
     public void onBindViewHolder(CustomViewHolder holder, int position) {
         holder.bindTo(getItem(position));
     }
     
 }

public abstract class CustomViewHolder extends RecyclerView.ViewHolder {
       public abstract void bindTo(FirsebaseItem item);
}

public class ViewHolder1 extends CustomViewHolder () {...}
public class ViewHolder2 extends CustomViewHolder () {...}
public class ViewHolder3 extends CustomViewHolder () {...}

이상입니다.

핵심은 RecyclerView에 ViewHolder에서 바인딩을 할 데이터를 전달할 때 ViewType도 같이 전달해서 ViewType에 따라 다른 ViewHolder를 사용하도록 하면 됩니다.

도움이 되시길.

spark (226,420 포인트) 님이 2020년 11월 16일 답변
...