Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
130 views
in Technique[技术] by (71.8m points)

java - ViewModel not retrieving data on Fragment´s first onCreateView

I'm trying to retrieve a list of alarms from my SQLite database. When I first enter the Fragment, the list is not retrieve but if I exit the Fragment and enter it again, it does retrieve it correctly.

The Fragment is part of an Activity (MainActivity) that contains 3 Fragments. The user can move between Fragments clicking on the tabs (TabLayout). The first Fragment uses the same method to retrieve the list. This first Fragment is used to create the list of alarms. The created alarms will repeat in the chosen week days (all Mondays, Tuesday etc) Then there is a second one, and finally the third Fragment. This last one is used to display the alarms on a CalendarView

How can I make it retrieve the data at the first attempt in the third Fragment?

public class TabFragmentCalendar extends Fragment {
    private View view;
    private List<EventDay> events = new ArrayList<>();
    private com.applandeo.materialcalendarview.CalendarView calendarView;
    private MyViewModel myViewModel;
    private ArrayList<Alarm> listAlarms = new ArrayList<>();
    private ExecutorService executorService;

    public TabFragmentCalendario() {}

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        
        view = inflater.inflate(R.layout.fragment_tab_calendar, container, false);
        
        myViewModel = new ViewModelProvider(this).get(MyViewModel.class);
        myViewModel.getAllAlarms().observe(getViewLifecycleOwner(), new Observer<List<Alarm>>() {
            @Override
            public void onChanged(List<Alarm> alarms) {
                listAlarms = (ArrayList<Alarm>) alarms;
            }
        });

        for(Alarm alarm : listAlarms){
            Log.d("FragmentCalendar", "Alarm = " + alarm.getHour() + ":" + alarm.getMinute());
        } // To check if the alarms are retrieved

        
        calendarView = view.findViewById(R.id.calendarView);
        executorService = Executors.newSingleThreadExecutor();
        executorService.execute(new DisplayEvents(calendarView, events, listAlarms));
        
        return view;

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        //popularCalendario.interrupt();
        executorService.shutdown();
    }

As you can see, I created a new thread in order to display the alarms in the CalendarView. The alarms are created to be repeated in the chosen week days (all Mondays).

Here is the code for that thread.

public class DisplayEvents implements Runnable {
    private final List<EventDay> events;
    private final CalendarView calendarView;
    private final ArrayList<Alarm> listAlarms;

    public DisplayEventos(CalendarView calendarView, List<EventDay> events, ArrayList<Alarm> listAlarms) {
        this.calendarView = calendarView;
        this.events = events;
        this.listAlarms = listAlarms;
    }

    @Override
    public void run() {
        for (Alarm alarm : listAlarms) {
            for (int j = 0; j < 12; j++) {
                if (alarma.getMonday()) {
                    for (int i = 1; i <= 5; i++) {
                        Calendar calendar = Calendar.getInstance();
                        calendar.set(Calendar.MONTH, j);
                        calendar.set(Calendar.DAY_OF_WEEK, 2);
                        calendar.set(Calendar.WEEK_OF_MONTH, i);
                        events.add(new EventDay(calendar, R.drawable.ic_alarm));
                    }
                }
                if (alarm.getTuesday()) {
                    for (int i = 1; i <= 5; i++) {
                        Calendar calendar = Calendar.getInstance();
                        calendar.set(Calendar.MONTH, j);
                        calendar.set(Calendar.DAY_OF_WEEK, 3);
                        calendar.set(Calendar.WEEK_OF_MONTH, i);
                        events.add(new EventDay(calendar, R.drawable.ic_alarm));
                    }
                }
                if (alarma.getWednesday()) {
                    for (int i = 1; i <= 5; i++) {
                        Calendar calendar = Calendar.getInstance();
                        calendar.set(Calendar.MONTH, j);
                        calendar.set(Calendar.DAY_OF_WEEK, 4);
                        calendar.set(Calendar.WEEK_OF_MONTH, i);
                        events.add(new EventDay(calendar, R.drawable.ic_alarm));
                    }
                }
                if (alarma.getThursday()) {
                    for (int i = 1; i <= 5; i++) {
                        Calendar calendar = Calendar.getInstance();
                        calendar.set(Calendar.MONTH, j);
                        calendar.set(Calendar.DAY_OF_WEEK, 5);
                        calendar.set(Calendar.WEEK_OF_MONTH, i);
                        events.add(new EventDay(calendar, R.drawable.ic_alarm));
                    }
                }
                if (alarma.getFriday()) {
                    for (int i = 1; i <= 5; i++) {
                        Calendar calendar = Calendar.getInstance();
                        calendar.set(Calendar.MONTH, j);
                        calendar.set(Calendar.DAY_OF_WEEK, 6);
                        calendar.set(Calendar.WEEK_OF_MONTH, i);
                        events.add(new EventDay(calendar, R.drawable.ic_alarm));
                    }
                }
                if (alarma.getSaturday()) {
                    for (int i = 1; i <= 5; i++) {
                        Calendar calendar = Calendar.getInstance();
                        calendar.set(Calendar.MONTH, j);
                        calendar.set(Calendar.DAY_OF_WEEK, 7);
                        calendar.set(Calendar.WEEK_OF_MONTH, i);
                        events.add(new EventDay(calendar, R.drawable.ic_alarm));
                    }
                }
                if (alarma.getSunday()) {
                    for (int i = 1; i <= 5; i++) {
                        Calendar calendar = Calendar.getInstance();
                        calendar.set(Calendar.MONTH, j);
                        calendar.set(Calendar.DAY_OF_WEEK, 1);
                        calendar.set(Calendar.WEEK_OF_MONTH, i);
                        events.add(new EventDay(calendar, R.drawable.ic_alarm));
                    }
                }
            }
        }
        
        calendarView.post(new Runnable() {
            @Override
            public void run() {
                calendarView.setEvents(events);
            }
        });
    }
}

Android Studio says that:

I/Choreographer: Skipped 89 frames! The application may be doing too much work on its main thread.

I'm new to this world and I know that I'm making lots of mistakes. Any advice is welcome :)

question from:https://stackoverflow.com/questions/65918561/viewmodel-not-retrieving-data-on-fragment%c2%b4s-first-oncreateview

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

change your onCreateView method like this

 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    
    view = inflater.inflate(R.layout.fragment_tab_calendar, container, false);

    calendarView = view.findViewById(R.id.calendarView);
    executorService = Executors.newSingleThreadExecutor();

    myViewModel = new ViewModelProvider(this).get(MyViewModel.class);
    myViewModel.getAllAlarms().observe(getViewLifecycleOwner(), new Observer<List<Alarm>>() {
        @Override
        public void onChanged(List<Alarm> alarms) {
            listAlarms = (ArrayList<Alarm>) alarms;
           executorService.execute(new DisplayEvents(calendarView, events, listAlarms));
        }
    });

    for(Alarm alarm : listAlarms){
        Log.d("FragmentCalendar", "Alarm = " + alarm.getHour() + ":" + alarm.getMinute());
    } // To check if the alarms are retrieved

    
    
    
    
    
    return view;

}

Because in your code executorService.execute(new DisplayEvents(calendarView, events, listAlarms)); is called before onChanged method return list of alarms

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...