private void RestartSchedulesRenderingSubsystem() { IReadOnlyDictionary <Int32, Schedule> schedules = _application.Manager.Schedules; UpdateToolbarMenu(); if (schedules.Count == 0) { _toolbarTitle.SetText(Resource.String.welcomeToolbarTitle); _tabLayout.Visibility = ViewStates.Gone; _fab.Visibility = ViewStates.Gone; _currentSubjectHighlightTimer.Stop(); ShowLayoutMessage(Resource.String.welcomeMessage); _activityState = MainActivityState.DisplaysMessage; return; } SetSchedulesMenu(schedules); ShowViewPager(); _viewPager = FindViewById <ViewPager>(Resource.Id.scheduleViewPager); // Bug: если после запуска приложения перелистнуть страницу расписания влево или вправо, то // затем при изменении ориентации устройства событие по неизвестной причине срабатывает // дважды, причем оба раза с разными значениями позиции. В результате, при каждом повороте // экрана дата увеличивается/уменьшается (в зависимости от того, куда изначально свайпнуть), // но таблица с расписанием не обновляется. _viewPager.PageSelected += (s, e) => { DateTime date = _pagerAdapter.RenderingDateRange.GetDateByIndex(e.Position); _application.Preferences.CurrentScheduleDate = date; }; // Пересоздавать адаптер необходимо при каждом перезапуске подсистемы рендеринга, иначе // на активной в момент перезапуска вкладке не отрисуется фрагмент. _pagerAdapter = new SchedulesPagerAdapter( SupportFragmentManager, _application.Preferences.CurrentScheduleDate ); _tabLayout.Visibility = ViewStates.Visible; _tabLayout.SetupWithViewPager(_viewPager); Int32 SelectScheduleToDisplay() { Int32 currentId = _application.Preferences.CurrentScheduleId; if (currentId == 0) { return(schedules.Keys.First()); } return(schedules.ContainsKey(currentId) ? currentId : schedules.Keys.First()); } Int32 scheduleId = SelectScheduleToDisplay(); ShowSchedule(scheduleId); _fab.Visibility = _application.Preferences.UseFabDateSelector ? ViewStates.Visible : ViewStates.Gone; _currentSubjectHighlightTimer.Start(); }
private void RestartSchedulesRenderingSubsystem(Int32 preferredScheduleId = 0) { if (_stateManager.CurrentState == MainActivityState.NotInitialized) { return; } IReadOnlyDictionary <Int32, Schedule> schedules = _application.Manager.Schedules; // Невоспроизводимая искусственно ситуация, которая хоть и очень редко, но роняет приложение. if (schedules == null) { UiException exception = new UiException("Unexpected null value of Schedules property."); exception.Data["_stateManager.CurrentState"] = _stateManager.CurrentState; exception.Data["_application.IsInitialized"] = _application.IsInitialized; _application.Logger.Log(exception); ShowLayoutMessage(Resource.String.restartSchedulesRenderingSubsystemErrorMessage, true); return; } IReadOnlyList <Schedule> sortedSchedules = schedules.Select(s => s.Value) .OrderBy(s => s, new SchedulesComparer()) .ToList(); UpdateToolbarMenu(); ShowSchedulesFeatureDiscoveryTargetsSequence(sortedSchedules.Count); if (sortedSchedules.Count == 0) { _toolbarTitle.SetText(Resource.String.welcomeToolbarTitle); _tabLayout.Visibility = ViewStates.Gone; _fab.Visibility = ViewStates.Gone; _currentSubjectHighlightTimer.Stop(); ShowLayoutMessage(Resource.String.welcomeMessage); _stateManager.SetState(MainActivityState.WelcomeMessageDisplayed); return; } SetSchedulesMenu(sortedSchedules); ShowViewPager(); CustomSwipeRefreshLayout scheduleRefreshLayout = FindViewById <CustomSwipeRefreshLayout>( Resource.Id.scheduleSwipeRefreshLayout); scheduleRefreshLayout.SetColorSchemeResources(Resource.Color.primaryDay); scheduleRefreshLayout.Refresh += async(s, e) => { await DownloadScheduleWithCheckPermissionAsync(_application.Preferences.CurrentScheduleId); scheduleRefreshLayout.Refreshing = false; }; _viewPager = FindViewById <ViewPager>(Resource.Id.scheduleViewPager); // Bug: если после запуска приложения перелистнуть страницу расписания влево или вправо, то // затем при изменении ориентации устройства событие по неизвестной причине срабатывает // дважды, причем оба раза с разными значениями позиции. В результате, при каждом повороте // экрана дата увеличивается/уменьшается (в зависимости от того, куда изначально свайпнуть), // но таблица с расписанием не обновляется. // Судя по нагугленному – это не баг, а "by design": перед переходом на запрошенную страницу // активной делается либо одна из крайних, либо соседняя с запрашиваемой страница. _viewPager.PageSelected += (s, e) => { DateTime date = _pagerAdapter.RenderingDateRange.GetDateByIndex(e.Position); _application.Preferences.CurrentScheduleDate = date; }; // При приближении к границам отрисовываемого диапазона дат необходимо пересчитать его, // чтобы пользователю не нужно было совершать лишние телодвижения для дальнейшего просмотра. _viewPager.PageScrollStateChanged += (s, e) => { if (e.State != ViewPager.ScrollStateIdle) { return; } Int32 lastPageIndex = _pagerAdapter.RenderingDateRange.TotalDaysNumber - 1; // По одной странице с каждого края. if (_viewPager.CurrentItem == 0 || _viewPager.CurrentItem == lastPageIndex) { ViewPagerMoveToDate(_application.Preferences.CurrentScheduleDate, true, true); } }; // Пересоздавать адаптер необходимо при каждом перезапуске подсистемы рендеринга, иначе // на активной в момент перезапуска вкладке не отрисуется фрагмент. _pagerAdapter = new SchedulesPagerAdapter( SupportFragmentManager, _application.Preferences.CurrentScheduleDate ); _tabLayout.Visibility = ViewStates.Visible; _tabLayout.SetupWithViewPager(_viewPager); _fab.Visibility = _application.Preferences.UseFabDateSelector ? ViewStates.Visible : ViewStates.Gone; Int32 SelectScheduleToDisplay() { if (preferredScheduleId != 0 && schedules.ContainsKey(preferredScheduleId)) { return(preferredScheduleId); } Int32 currentId = _application.Preferences.CurrentScheduleId; if (currentId == 0) { return(sortedSchedules[0].ScheduleId); } return(schedules.ContainsKey(currentId) ? currentId : sortedSchedules[0].ScheduleId); } Int32 scheduleId = SelectScheduleToDisplay(); ShowSchedule(scheduleId); _currentSubjectHighlightTimer.Start(); }