В адаптере в методе bind устанавливаю данные из List (во фрагменте загружаю их туда из Firestore). Но еще нужны данные, которые находятся в другой коллекции. Здесь же пытаюсь создать другой запрос к Firestore и вывести данные, он прокрутка интерфейса зависает и иногда данные выводятся в неправильных карточках. Понимаю, что неправильно здесь так делать, но как сделать правильно не понимаю
Adapter
public class MeetingAdapter extends RecyclerView.Adapter<MeetingAdapter.MyViewHolder> {
private List<Meeting> meetingsList;
private Context context;
public MeetingAdapter(List<Meeting> meetingsList, Context context) {
this.meetingsList = meetingsList;
this.context = context;
}
@NonNull
@Override
public MeetingAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(context).inflate(R.layout.item_meeting, parent, false);
return new MeetingAdapter.MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull MeetingAdapter.MyViewHolder holder, final int position) {
bind(holder);
}
@Override
public int getItemCount() {
return meetingsList.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView title, dateAdd;
LinearLayout userLink;
ImageView photo;
MyViewHolder(View itemView) {
super(itemView);
title = itemView.findViewById(R.id.title);
dateAdd = itemView.findViewById(R.id.dateAdd);
userLink = itemView.findViewById(R.id.userLink);
photo = itemView.findViewById(R.id.photo);
}
}
private void bind(final MeetingAdapter.MyViewHolder holder) {
final int position = holder.getAdapterPosition();
DocumentReference docRef = FirebaseFirestore.getInstance().collection("users").document(meetingsList.get(position).getUser() + "");
docRef.addSnapshotListener(new EventListener<DocumentSnapshot>() {
@Override
public void onEvent(@Nullable DocumentSnapshot snapshot, @Nullable FirebaseFirestoreException e) {
if (e != null) {
return;
}
if (snapshot != null && snapshot.exists()) {
holder.title.setText(snapshot.getData().get("name") + "");
}
}
});
holder.dateAdd.setText(meetingsList.get(position).getDateAdd());
holder.userLink.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("butt", "click " + position);
MeetingAdapter.this.notifyItemChanged(position, "payload " + position);
Toast.makeText(context, "userId " + meetingsList.get(position).getUser(), Toast.LENGTH_SHORT).show();
}
});
}
}
Fragment
public class HomeFragment extends Fragment {
private final int LIMIT_ITEM_LOAD = 5;
private View item_1, item_2, item_3, item_4, item_5;
private SwipeRefreshLayout swipeRefresh;
private RotateLoading loading;
private RecyclerView recyclerView;
private LinearLayoutManager linearLayoutManager;
private DocumentSnapshot lastVisible;
private boolean isScrolling;
private boolean isLastItemReached;
private List<Meeting> list;
private MeetingAdapter adapter;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home, container, false);
item_1 = getActivity().findViewById(R.id.item_1);
item_2 = getActivity().findViewById(R.id.item_2);
item_3 = getActivity().findViewById(R.id.item_3);
item_4 = getActivity().findViewById(R.id.item_4);
item_5 = getActivity().findViewById(R.id.item_5);
loading = getActivity().findViewById(R.id.loading);
BottomNavigationView navigation = getActivity().findViewById(R.id.navigation);
navigation.getMenu().getItem(0).setChecked(true);
setBorderItemSelected(item_1);
Toolbar toolbar = view.findViewById(R.id.toolbar);
((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);
((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayShowTitleEnabled(false);
toolbar.setTitle("Лента событий");
setHasOptionsMenu(true);
recyclerView = view.findViewById(R.id.recyclerView);
linearLayoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(linearLayoutManager);
swipeRefresh = view.findViewById(R.id.swipeRefresh);
swipeRefresh.setColorSchemeResources(
R.color.orange_300,
R.color.pink_300,
R.color.green_300,
R.color.blue_300);
swipeRefresh.setOnRefreshListener(refreshListener);
loading.start();
getDataFirebase();
recyclerView.addOnScrollListener(onScrollListener);
return view;
}
private SwipeRefreshLayout.OnRefreshListener refreshListener = new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override public void run() {
swipeRefresh.setRefreshing(true);
refreshPage();
swipeRefresh.setRefreshing(false);
}
},1000);
}
};
private void getDataFirebase() {
Query query = FirebaseFirestore.getInstance()
.collection("meetings")
.orderBy("id", Query.Direction.DESCENDING)
.limit(LIMIT_ITEM_LOAD);
query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
list = new ArrayList<>();
for (DocumentSnapshot document : task.getResult()) {
Meeting meeting = document.toObject(Meeting.class);
list.add(meeting);
// adapter.notifyItemInserted(list.size());
}
adapter = new MeetingAdapter(list, getContext());
recyclerView.setAdapter(adapter);
lastVisible = task.getResult().getDocuments().get(task.getResult().size() - 1);
Toast.makeText(getContext(), "Загружено. lastVisible = " + lastVisible.get("id"), Toast.LENGTH_SHORT).show();
loading.stop();
recyclerView.addOnScrollListener(onScrollListener);
}
}
});
}
private void refreshPage() {
isLastItemReached = false;
Query query = FirebaseFirestore.getInstance()
.collection("meetings")
.orderBy("id", Query.Direction.DESCENDING)
.limit(LIMIT_ITEM_LOAD);
query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
list.clear();
for (DocumentSnapshot document : task.getResult()) {
Meeting meeting = document.toObject(Meeting.class);
list.add(meeting);
}
adapter = new MeetingAdapter(list, getContext());
recyclerView.setAdapter(adapter);
// adapter.notifyDataSetChanged();
lastVisible = task.getResult().getDocuments().get(task.getResult().size() - 1);
Toast.makeText(getContext(), "Обновление завершено. lastVisible = " + lastVisible.get("id")
+ " / " + isScrolling
+ " / " + isLastItemReached, Toast.LENGTH_SHORT).show();
recyclerView.addOnScrollListener(onScrollListener);
}
}
});
}
private RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
isScrolling = true;
// Toast.makeText(getContext(), "Крутим", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int firstVisibleItem = linearLayoutManager.findFirstVisibleItemPosition();
int visibleItemCount = linearLayoutManager.getChildCount();
int totalItemCount = linearLayoutManager.getItemCount();
Log.d("Ok","firstVisibleItem = " + firstVisibleItem);
Log.d("Ok","visibleItemCount = " + visibleItemCount);
Log.d("Ok","totalItemCount = " + totalItemCount);
if (isScrolling && (firstVisibleItem + visibleItemCount == totalItemCount) && !isLastItemReached) {
isScrolling = false;
Query nextQuery = FirebaseFirestore.getInstance()
.collection("meetings")
.orderBy("id", Query.Direction.DESCENDING)
.startAfter(lastVisible)
.limit(LIMIT_ITEM_LOAD);
nextQuery.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
for (DocumentSnapshot document : task.getResult()) {
Meeting meeting = document.toObject(Meeting.class);
list.add(meeting);
}
adapter.notifyDataSetChanged();
if (task.getResult().size() < LIMIT_ITEM_LOAD) {
isLastItemReached = true;
Toast.makeText(getContext(), "Конец списка. lastVisible = " + lastVisible.get("id"), Toast.LENGTH_SHORT).show();
} else {
lastVisible = task.getResult().getDocuments().get(task.getResult().size() - 1);
Toast.makeText(getContext(), "Подгрузка завершена. lastVisible = " + lastVisible.get("id"), Toast.LENGTH_SHORT).show();
}
}
});
}
}
};
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_filtration:
//
break;
default:
break;
}
return true;
}
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.toolbar_home, menu);
super.onCreateOptionsMenu(menu, inflater);
}
public void setBorderItemSelected(View view) {
item_1.setBackgroundColor(getResources().getColor(android.R.color.transparent));
item_2.setBackgroundColor(getResources().getColor(android.R.color.transparent));
item_3.setBackgroundColor(getResources().getColor(android.R.color.transparent));
item_4.setBackgroundColor(getResources().getColor(android.R.color.transparent));
item_5.setBackgroundColor(getResources().getColor(android.R.color.transparent));
view.setBackgroundColor(getResources().getColor(R.color.white));
}
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Сначала я ввожу словами числаЗатем на вход программе подаётся значение N — количество записей, которые необходимо обработать Следующие...
Делаю приложение используя Spring MVC и Spring Web Flow, сделав некий flow я могу попасть на него используя ${flowExecutionUrl} в JSP файле, но из-за некой, невиданной...