Итак, в основном то, что я пытаюсь сделать, - это показать кучу объектов типа Post в ленте моего Android приложения (HomeFragment). Сообщения успешно извлекаются из Firestore (я проверял отладчик), но почему-то не все из них загружаются в recyclerView. ItemViewHolder загружается только с тем, как я определил его как XML, поля, заполненные Ipsum лора.
Это будет мой код:
HomeFragment:
public class HomeFragment extends Fragment {
private RecyclerView recyclerView;
private RecyclerViewAdapter recyclerViewAdapter;
private boolean isLoading = false;
private ArrayList<String> rowsArrayList = new ArrayList<>();
public static ArrayList<Post> appliedToList = new ArrayList<>();
private User currentUser = new User();
private View root;
private TextView userState;
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private String userId = FirebaseAuth.getInstance().getCurrentUser() != null ? FirebaseAuth.getInstance().getCurrentUser().getUid() : null;
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
root = inflater.inflate(R.layout.fragment_home, container, false);
setState();
appliedToPostsRetrieverFromHomePage(getContext());
checkForPostFragment();
recyclerView = root.findViewById(R.id.recyclerView);
initAdapter();
initScrollListener();
return root;
}
private void initAdapter() {
recyclerViewAdapter = new RecyclerViewAdapter(getActivity(), 2);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(recyclerViewAdapter);
}
private void initScrollListener() {
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
if (!isLoading) {
if (linearLayoutManager != null && linearLayoutManager.findLastCompletelyVisibleItemPosition() == rowsArrayList.size() - 1) {
//bottom of list!
loadMore();
isLoading = true;
}
}
}
});
}
private void loadMore() {
rowsArrayList.add(null);
recyclerViewAdapter.notifyItemInserted(rowsArrayList.size() - 1);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
rowsArrayList.remove(rowsArrayList.size() - 1);
int scrollPosition = rowsArrayList.size();
recyclerViewAdapter.notifyItemRemoved(scrollPosition);
int currentSize = scrollPosition;
int nextLimit = currentSize + 10;
while (currentSize - 1 < nextLimit) {
rowsArrayList.add("Item " + currentSize);
currentSize++;
}
recyclerViewAdapter.notifyDataSetChanged();
isLoading = false;
}
}, 2000);
}
@Override
public void onAttachFragment(@NonNull Fragment fragment) {
super.onAttachFragment(fragment);
}
RecyclerViewAdapter:
Все типы представлений представляют собой своего рода один и тот же макет, единственная разница между ними заключается в том, что написано на определенной кнопке. Помните, некоторые сообщения успешно загружены!
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final int VIEW_TYPE_APPLY = 0;
private final int VIEW_TYPE_MORE = 1;
private final int VIEW_TYPE_BEGIN = 2;
private final int VIEW_TYPE_PENDING = 3;
private final int VIEW_TYPE_END = 4;
private final int VIEW_TYPE_ON_GOING = 5;
private final int VIEW_TYPE_LOADING = 6;
private ArrayList<Post> list = new ArrayList();
private static final String TAG = RecyclerViewAdapter.class.getSimpleName();
private Context context;
private User currentUser;
private int recyclerType;
static ArrayList<User> applicantsList = new ArrayList<>();
private String userId = FirebaseAuth.getInstance().getCurrentUser() != null ? FirebaseAuth.getInstance().getCurrentUser().getUid() : null;
private FirebaseFirestore db = FirebaseFirestore.getInstance();
public RecyclerViewAdapter(Context context, int recyclerType) {
this.context = context;
this.recyclerType = recyclerType;
if (recyclerType == 0) {
myPostsRetriever(context);
} else if (recyclerType == 1) {
appliedToPostsRetriever(context);
} else if (recyclerType == 2) {
homePostsRetriever(context);
}
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_APPLY) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row_apply, parent, false);
return new ItemViewHolder(view);
} else if (viewType == VIEW_TYPE_MORE) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row_more, parent, false);
return new LoadingViewHolder(view);
} else if (viewType == VIEW_TYPE_BEGIN) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row_begin, parent, false);
return new LoadingViewHolder(view);
} else if (viewType == VIEW_TYPE_PENDING) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row_pending, parent, false);
return new LoadingViewHolder(view);
} else if (viewType == VIEW_TYPE_END) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row_end, parent, false);
return new LoadingViewHolder(view);
} else if (viewType == VIEW_TYPE_ON_GOING) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row_on_going, parent, false);
return new LoadingViewHolder(view);
} else {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_loading, parent, false);
return new LoadingViewHolder(view);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
if (viewHolder instanceof ItemViewHolder) {
populateItemRows((ItemViewHolder) viewHolder, position);
} else if (viewHolder instanceof LoadingViewHolder) {
showLoadingView((LoadingViewHolder) viewHolder, position);
}
}
@Override
public int getItemCount() {
return list == null ? 0 : list.size();
}
@Override
public int getItemViewType(int position) {
if (list.get(position) != null) {
if (!list.get(position).getOwner().equals(userId) &&
!checkIfAlreadyAppliedToPost(position) &&
list.get(position).getMinNeededPersons() >= list.get(position).getApplicants()) {
return VIEW_TYPE_APPLY;
} else if (recyclerType == 1) {
return VIEW_TYPE_MORE;
} else if (list.get(position).getOwner().equals(userId) && timeCheck(list.get(position))) {
return VIEW_TYPE_BEGIN;
} else if (list.get(position).getOwner().equals(userId) && checkIfStarted(position)
|| !list.get(position).getOwner().equals(userId) && checkIfAlreadyAppliedToPost(position) && !checkIfStarted(position)) {
return VIEW_TYPE_PENDING;
} else if (list.get(position).getOwner().equals(userId) && checkIfStarted(position)) {
return VIEW_TYPE_END;
} else if (!list.get(position).getOwner().equals(userId) && checkIfStarted(position)){
return VIEW_TYPE_ON_GOING;
}else if (list.get(position).getOwner().equals(userId))
return VIEW_TYPE_MORE;
}
return VIEW_TYPE_LOADING;
}
private class ItemViewHolder extends RecyclerView.ViewHolder {
TextView title;
TextView description;
TextView location;
TextView minNeededPersons;
TextView maxNeededPersons;
TextView reward;
TextView time;
CheckBox physical;
Button button;
ItemViewHolder(@NonNull View itemView) {
super(itemView);
title = itemView.findViewById(R.id.postTitle);
description = itemView.findViewById(R.id.postDescription);
location = itemView.findViewById(R.id.postLocationText);
time = itemView.findViewById((R.id.postDateAndTime));
minNeededPersons = itemView.findViewById(R.id.people);
maxNeededPersons = itemView.findViewById(R.id.people);
reward = itemView.findViewById(R.id.reward);
physical = itemView.findViewById(R.id.checkBox2);
button = itemView.findViewById(R.id.applyButton);
}
}
private class LoadingViewHolder extends RecyclerView.ViewHolder {
ProgressBar progressBar;
LoadingViewHolder(@NonNull View itemView) {
super(itemView);
progressBar = itemView.findViewById(R.id.progressBar);
}
}
private void showLoadingView(LoadingViewHolder viewHolder, int position) {
}
private void populateItemRows(ItemViewHolder viewHolder, int position) {
Post item = list.get(position);
viewHolder.title.setText(item.getTheTitle());
viewHolder.description.setText(item.getDescription());
viewHolder.location.setText(item.getLocation());
viewHolder.location.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent showLocation = new Intent(context, MapsActivity.class);
context.startActivity(showLocation);
}
});
viewHolder.minNeededPersons.setText(String.valueOf(item.getMinNeededPersons()));
viewHolder.maxNeededPersons.setText(String.valueOf(item.getMaxPersonsNeeded()));
viewHolder.reward.setText(String.valueOf(item.getReward()));
viewHolder.physical.setChecked(item.isPhysical());
Date timeAndDate = item.getTime().toDate();
viewHolder.time.setText(new SimpleDateFormat("HH:mm dd.MM.yyyy").format(timeAndDate));
viewHolder.button.setOnClickListener(new View.OnClickListener() {
@SuppressLint("SetTextI18n")
@Override
public void onClick(View v) {
if (viewHolder.button.getText().equals(context.getResources().getString(R.string.apply))) {
onApplyTapped(position);
viewHolder.button.setText(R.string.pending);
viewHolder.button.setBackgroundColor(Color.parseColor("#F2CF59"));
viewHolder.button.setClickable(false);
} else if (viewHolder.button.getText().equals(context.getResources().getString(R.string.begin_job))) {
onBeginTapped(position);
viewHolder.button.setText(R.string.end_job);
viewHolder.button.setBackgroundColor(Color.parseColor("#F8CA9D"));
} else if (viewHolder.button.getText().equals(context.getResources().getString(R.string.end_job))) {
onEndTapped(position);
viewHolder.button.setBackgroundColor(Color.parseColor("#FB8E7E"));
viewHolder.button.setClickable(false);
viewHolder.button.setText(R.string.finished);
}
}
});
viewHolder.itemView.findViewById(R.id.seePostButton).setOnClickListener(new View.OnClickListener()
{ not relevant }
private void homePostsRetriever(Context context) {
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
rootRef.collectionGroup("posts").limit(10).get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot documentSnapshots) {
for (DocumentSnapshot documentSnapshot : documentSnapshots.getDocuments()) {
Post post = new Post();
post.setAvailability(documentSnapshot.getBoolean("available"));
post.setTitle(documentSnapshot.getString("title"));
post.setDescription(documentSnapshot.getString("description"));
post.setLocation(documentSnapshot.getString("location"));
post.setApplicants(documentSnapshot.getLong("applicants").intValue());
post.setOwner(documentSnapshot.getString("owner"));
post.setMinNeededPersons(documentSnapshot.getLong("minNrOfPeople").intValue());
post.setMaxPersonsNeeded(documentSnapshot.getLong("maxNrOfPeople").intValue());
post.setReward(Objects.requireNonNull(documentSnapshot.getLong("reward")).floatValue());
post.setPhysical(documentSnapshot.getBoolean("physicalExcertion"));
post.setTime(documentSnapshot.getTimestamp("time"));
post.setId(documentSnapshot.getId());
post.setStarted(documentSnapshot.getBoolean("started"));
list.add(post);
}
notifyDataSetChanged();
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Toast.makeText(context, "No document found", Toast.LENGTH_SHORT).show();
}
});
}