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를 사용하도록 하면 됩니다.
도움이 되시길.