Exemplo n.º 1
0
        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();
        }
Exemplo n.º 2
0
        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();
        }