0

Problem: I have a horizontal scrolling calendar at the top and there is a recycler view underneath displaying the events for that date. I want to display the events for the current date as default and if I click on another day, it will show events on that day.

Ex. By default, if today is July 4th, the calendar will be selected at July 4th and it will only show the July 4th events, then if I click/press July 5th on the calendar, the events for July 4th should disappear and the events for July 5th should appear in the RecyclerView.

My attempt:

    private RecyclerView mFirestoreList;
    private FirebaseFirestore firebaseFirestore;
    private FirestoreRecyclerAdapter adapter;
    private String day = Integer.toString(Calendar.getInstance().get(Calendar.DAY_OF_MONTH));
    private String month = Integer.toString(Calendar.getInstance().get(Calendar.MARCH));
    private String year =  Integer.toString(Calendar.getInstance().get(Calendar.YEAR));

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

        createEvent = (Button) v.findViewById(R.id.createEventBtn2);
        logout = (Button) v.findViewById(R.id.logoutBtn2);

        HorizontalPicker picker = (HorizontalPicker) v.findViewById(R.id.datePicker);
        picker.setListener(this).setDays(120).setOffset(7).setDateSelectedColor(Color.DKGRAY)
                .setDateSelectedTextColor(Color.WHITE)
                .setMonthAndYearTextColor(Color.DKGRAY)
                .setTodayButtonTextColor(getResources().getColor(R.color.colorPrimary))
                .setTodayDateTextColor(getResources().getColor(R.color.colorPrimary))
                .setTodayDateBackgroundColor(Color.GRAY)
                .setUnselectedDayTextColor(Color.DKGRAY)
                .setDayOfWeekTextColor(Color.DKGRAY)
                .setUnselectedDayTextColor(getResources().getColor(R.color.primaryTextColor))
                .showTodayButton(false).init();
        picker.setBackgroundColor(Color.LTGRAY);
        picker.setDate(new DateTime());

        firebaseFirestore = FirebaseFirestore.getInstance();
        mFirestoreList = v.findViewById(R.id.firestore_list);

        //Query
        Query query = firebaseFirestore.collection(year).document(month).collection(day);
        //Recycler options
        FirestoreRecyclerOptions<EventModel> options = new FirestoreRecyclerOptions.Builder<EventModel>()
                .setQuery(query, EventModel.class)
                .build();

        adapter = new FirestoreRecyclerAdapter<EventModel, EventsViewHolder>(options) {

            @NonNull
            @Override
            public EventsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_list_item, parent, false);
                return new EventsViewHolder(view);
            }

            @Override
            protected void onBindViewHolder(@NonNull EventsViewHolder holder, int position, @NonNull EventModel model) {
                holder.className.setText(model.getClassName());
                holder.location.setText(model.getLocation());
                holder.time.setText(model.getTime());
            }
        };

        mFirestoreList.setHasFixedSize(true);
        mFirestoreList.setLayoutManager(new LinearLayoutManager(getContext()));
        mFirestoreList.setAdapter(adapter);


      createEvent.setOnClickListener(new View.OnClickListener() {
          @Override
        public void onClick(View v) {
            openCreatePage();
        }
       });

        logout.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View v) {
                FirebaseAuth.getInstance().signOut();
                startActivity(new Intent(v.getContext(), Register.class));
            }
        });
        return v;
    }
    @Override
    public void onDateSelected(DateTime dateSelected){
        Toast.makeText(v.getContext(), dateSelected.toString(), Toast.LENGTH_SHORT).show();
        day = Integer.toString(dateSelected.getDayOfMonth());
        month = Integer.toString(dateSelected.getMonthOfYear());
        year = Integer.toString(dateSelected.getYear());
    }

    private class EventsViewHolder extends RecyclerView.ViewHolder{

        private TextView className;
        private TextView location;
        private TextView time;
        public EventsViewHolder(@NonNull View itemView) {
            super(itemView);

            className = itemView.findViewById(R.id.classNameSLI);
            location = itemView.findViewById(R.id.locationSLI);
            time = itemView.findViewById(R.id.timeSLI);

        }
    }

    @Override
    public void onStop() {
        super.onStop();
        adapter.stopListening();
    }

    @Override
    public void onStart() {
        super.onStart();
        adapter.startListening();
    }

What I was trying to do was to change the day, month, and year variables and since those are changing, the query would change, but it does not.

Is this possible to do? What is it I'm looking for but can't find?

David
  • 5
  • 4

1 Answers1

0

A query for a FirebaseRecyclerAdapter cannot be changed once the adapter is created. You can read more about why in this answer.

What you could do, is place the creation and setting of the adapter in a method where you provide the day, month, and year, like so:

private void createAndSetAdapter(String day, String month, String year) {

    //Query
    Query query = firebaseFirestore.collection(year).document(month).collection(day);
    //Recycler options
    FirestoreRecyclerOptions < EventModel > options = new FirestoreRecyclerOptions.Builder < EventModel > ()
        .setQuery(query, EventModel.class)
        .build();

    adapter = new FirestoreRecyclerAdapter < EventModel, EventsViewHolder > (options) {

        @NonNull
        @Override
        public EventsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_list_item, parent, false);
            return new EventsViewHolder(view);
        }

        @Override
        protected void onBindViewHolder(@NonNull EventsViewHolder holder, int position, @NonNull EventModel model) {
            holder.className.setText(model.getClassName());
            holder.location.setText(model.getLocation());
            holder.time.setText(model.getTime());
        }
    };

    // Leave these two lines out of this method, and keep it inside your onCreate
    // mFirestoreList.setHasFixedSize(true);
    // mFirestoreList.setLayoutManager(new LinearLayoutManager(getContext()));

    mFirestoreList.setAdapter(adapter);
}

And then call this method inside your onDateSelected() method:

@Override
public void onDateSelected(DateTime dateSelected) {
    Toast.makeText(v.getContext(), dateSelected.toString(), Toast.LENGTH_SHORT).show();
    day = Integer.toString(dateSelected.getDayOfMonth());
    month = Integer.toString(dateSelected.getMonthOfYear());
    year = Integer.toString(dateSelected.getYear());
    createAndSetAdapter(day, month, year)
}

Don't forget to use this method inside your onCreate as well!

Ryan
  • 948
  • 6
  • 20
  • This solution works partly. I have the issue that now, if I create a new event for July 4th, all of the events for July 4th appear. However, if I click/press on July 5th and come back to July 4th, the events disappear. Finally, just by clicking on another date, it does not fill the RecyclerView. If I click/press on July 5th, the events for July 5th do not show up. Is it a problem with the adapter? – David Jul 04 '20 at 18:07
  • I have noticed you never make a call to your method `onDateSelected`. This should be called when you select a date from the picker. – Ryan Jul 06 '20 at 10:47