示例#1
0
        private View CreateSubjectView(LayoutInflater inflater, ViewGroup container, Subject subject,
            IEnumerable<Subject> relatedSubjects, Boolean shouldHighlightSubject)
        {
            View layout = inflater.Inflate(Resource.Layout.subject, container, false);

            if (shouldHighlightSubject)
            {
                layout.SetBackgroundColor(_dividerColor);
            }

            TextView times = layout.FindViewById<TextView>(Resource.Id.subjectTimesTextView);
            times.Text = subject.From.ToString("HH:mm");

            TextView title = layout.FindViewById<TextView>(Resource.Id.subjectTitleTextView);
            title.Text = subject.Title;

            TextView lecturer = layout.FindViewById<TextView>(Resource.Id.subjectLecturerTextView);
            lecturer.MovementMethod = LinkMovementMethod.Instance;
            lecturer.Text = @"¯\_(ツ)_/¯";

            // Из-за одинаковых идентификаторов в разных фрагментах в LinkMovementMethod вероятно возникает
            // конфликт, в результате которого при переходе на другое расписание по щелчку на нем, все поля
            // lecturer нового фрагмента принимают значение, которое содержалось в поле, по которому ранее
            // щелкнули. Проблема решается присвоением каждому экземпляру поля уникального идентификатора.
            lecturer.Id = View.GenerateViewId();

            TextView auditorium = layout.FindViewById<TextView>(Resource.Id.subjectAuditoriumTextView);
            auditorium.Text = subject.Auditorium;

            if (_application.Preferences.DisplaySubjectEndTime)
            {
                // Поле lecturer выравнивается на одной высоте с audience при однострочном значении title.
                title.SetMinLines(2);

                times.Append("\n");
                times.Append(subject.To.ToString("HH:mm").ToColored(_tertiaryTextColor));
            }

            if (relatedSubjects == null)
            {
                IScheduleReference lecturerOrGroup = subject.Lecturer as IScheduleReference
                    ?? subject.Group as IScheduleReference;

                if (lecturerOrGroup != null)
                {
                    lecturer.Text = lecturerOrGroup.Name;
                    lecturer.Click += (s, e) => _schedulesSwitcherCallback(lecturerOrGroup.ScheduleId);
                }

                return layout;
            }

            CustomClickableSpan CreateSwitchSchedulesClickableSpan(Int32 scheduleId)
            {
                CustomClickableSpan span = new CustomClickableSpan(_secondaryTextColor);
                span.Click += () => _schedulesSwitcherCallback?.Invoke(scheduleId);
                return span;
            }

            using SpannableStringBuilder builder = new SpannableStringBuilder(_multiGroupsPrefix + " ");

            Int32 scheduleId = subject.Group.ScheduleId;

            CustomClickableSpan schedulesSwitcherSpan = CreateSwitchSchedulesClickableSpan(scheduleId);
            builder.Append(scheduleId.ToString(), schedulesSwitcherSpan, SpanTypes.ExclusiveExclusive);

            foreach (Subject relatedSubject in relatedSubjects)
            {
                scheduleId = relatedSubject.Group.ScheduleId;

                builder.Append(", ");

                schedulesSwitcherSpan = CreateSwitchSchedulesClickableSpan(scheduleId);
                builder.Append(scheduleId.ToString(), schedulesSwitcherSpan, SpanTypes.ExclusiveExclusive);
            }

            lecturer.SetText(builder, TextView.BufferType.Spannable);

            return layout;
        }
示例#2
0
        private View CreateSubjectView(LayoutInflater inflater, ViewGroup container, Subject subject,
                                       IEnumerable <Subject> relatedSubjects, Boolean needHighlight)
        {
            View layout = inflater.Inflate(Resource.Layout.subject, container, false);

            if (needHighlight)
            {
                layout.SetBackgroundColor(_dividerColor);
            }

            TextView times = layout.FindViewById <TextView>(Resource.Id.subjectTimesTextView);

            times.Text = subject.From.ToString("HH:mm");

            TextView title = layout.FindViewById <TextView>(Resource.Id.subjectTitleTextView);

            title.Text = subject.Title;

            TextView lecturer = layout.FindViewById <TextView>(Resource.Id.subjectLecturerTextView);

            lecturer.MovementMethod = LinkMovementMethod.Instance;
            lecturer.Text           = @"¯\_(ツ)_/¯";

            // Из-за одинаковых идентификаторов в разных фрагментах в LinkMovementMethod вероятно возникает
            // конфликт, в результате которого при переходе на другое расписание по щелчку на нем, все поля
            // lecturer нового фрагмента принимают значение, которое содержалось в поле, по которому ранее
            // щелкнули. Проблема решается присвоением каждому экземпляру поля уникального идентификатора.
            lecturer.Id = View.GenerateViewId();

            TextView audienceView = layout.FindViewById <TextView>(Resource.Id.subjectAudienceTextView);

            audienceView.Text = subject.Audience;

            if (_application.Preferences.DisplaySubjectEndTime)
            {
                // Высота левой ячейки (match_parent) определяется высотой правой ячейки (wrap_content),
                // с целью выровнять их по высоте для корректного позиционирования номера аудитории.
                // Если фактическая высота левой ячейки меньше, чем требуется ее содержимому,
                // то оно будет перекрываться. На этапе рендеринга, когда уже известно сколько места
                // при данном тексте и ширине экрана займет название предмета, высота его контейнера
                // задается так, чтобы высота правой ячейки превосходила высоту содержимого левой.
                // Эта ситуация возникает только если включено отображаение времени окончания занятий
                // и при этом название предмета умещается в одну строку.
                title.ViewTreeObserver.PreDraw += (s, e) =>
                {
                    if (title.LineCount < 2)
                    {
                        title.SetLines(2);
                    }

                    e.Handled = true;
                };

                times.Append("\n");
                times.Append(subject.To.ToString("HH:mm").ToColored(_tertiaryTextColor));
            }

            if (relatedSubjects == null)
            {
                Lecturer lecturerOrGroup = subject.Lecturer ?? subject.Group;
                if (lecturerOrGroup != null)
                {
                    lecturer.Text   = lecturerOrGroup.Name;
                    lecturer.Click += (s, e) => _schedulesSwitcherCallback(lecturerOrGroup.ScheduleId);
                }

                return(layout);
            }

            CustomClickableSpan CreateSwitchSchedulesClickableSpan(Int32 scheduleId)
            {
                CustomClickableSpan span = new CustomClickableSpan(_secondaryTextColor);

                span.Click += () => _schedulesSwitcherCallback?.Invoke(scheduleId);
                return(span);
            }

            using (SpannableStringBuilder builder = new SpannableStringBuilder(_multiGroupsPrefix + " "))
            {
                Int32 scheduleId = subject.Group.ScheduleId;

                CustomClickableSpan schedulesSwitcher = CreateSwitchSchedulesClickableSpan(scheduleId);
                builder.Append(scheduleId.ToString(), schedulesSwitcher, SpanTypes.ExclusiveExclusive);

                foreach (Subject relatedSubject in relatedSubjects)
                {
                    scheduleId = relatedSubject.Group.ScheduleId;

                    builder.Append(", ");

                    schedulesSwitcher = CreateSwitchSchedulesClickableSpan(scheduleId);
                    builder.Append(scheduleId.ToString(), schedulesSwitcher, SpanTypes.ExclusiveExclusive);
                }

                lecturer.SetText(builder, TextView.BufferType.Spannable);
            }

            return(layout);
        }