Макет, на который я не раз смотрю почти каждый день, — это график выполнения работ. Он полезен для таких вещей, как графики транспортировки или распорядки учебных занятий. Итак, давайте составим простой макет для графика работ при помощи ListView с колонтитулами и настраиваемым ViewCell.
Структура страницы
Эта страница является простым ListView, и ничего сложного в ней нет. Я отключил разделители (Separators). И настроил RowHeight таким образом, чтобы было поинтереснее.
1 2 3 4 5 6 | <ListView x:Name="timelineListView" ItemTapped="timelineListView_ItemTapped" ItemsSource="{Binding .}" RowHeight="75" SeparatorVisibility="None"> |
Кроме того, Вы можете заметить, что ItemTapped у меня подключен, хотя это мало на что влияет:
1 2 3 4 | private void timelineListView_ItemTapped(object sender, ItemTappedEventArgs e) { timelineListView.SelectedItem = null; } |
Он просто отключает строку от выбора, главным образом потому, что все выглядит довольно плохо, когда выбрана одна из строк… но, конечно, в зависимости от макета, возможно, потребуется выполнить навигацию в стиле отношения «один ко многим» (Master / Detail).
Header
Если требуется, чтобы что-то отображалось над ListView и оно также прокручивалось с ListView, используйте Header.
Совет: Что бы вы ни делали, не ставьте ScrollView вокруг всей страницы. Если получатся вложенные контейнеры прокрутки (например, ScrollView с ListView внутри), то будет сплошное расстройство. Вместо этого, лучше использовать Header.
Что же касается этого нашего Header, то он всего лишь простая компоновка стека с некоторыми метками и небольшим количеством заполнений.
1 2 3 4 5 6 | <ListView.Header> <StackLayout Padding="20,40,0,30"> <Label Style="{StaticResource PageHeaderLabel}" Text="Class Schedule" /> <Label Style="{StaticResource SubHeaderLabel}" Text="8 Mar 2017" /> </StackLayout> </ListView.Header> |
Footer
Внизу списка мы только что поместили изображение. Не по какой-то особо веской причине, а просто чтобы немного оживить страницу и показать, как работает Footer. Вы можете легко избавиться от изображения и тогда получится красивый макет; я просто подумал, что надо его сюда включить, чтобы развить идею Header/Footer.
В нашем случае Footer содержит сетку с двумя строками. Настоящее фоновое изображение Footer.png занимает обе строки. Кроме того, здесь есть прозрачное изображение с градиентом от прозрачного к белому, которое накладывается на первую строку. Что, по сути, просто создает эффект затухания для изображения.
1 2 3 4 5 6 7 8 9 10 | <ListView.Footer> <Grid RowSpacing="0"> <Grid.RowDefinitions> <RowDefinition Height="64" /> <RowDefinition Height="100" /> </Grid.RowDefinitions> <Image Grid.RowSpan="2" Aspect="AspectFill" HorizontalOptions="Fill" VerticalOptions="Start" Source="YogaImage.png" /> <Image Aspect="Fill" Grid.RowSpan="2" HorizontalOptions="Fill" Source="FadeToWhite.png" /> </Grid> </ListView.Footer> |
ViewCell
Самое интересное же происходит во ViewCell, что определяет, как будет выглядеть каждая строка.
В сущности это всего лишь простая сетка с тремя столбцами и двумя строками.
И единственная действительно интересная ее часть — это настоящие линии и окружности, которые формируют временную шкалу. Это достигается при использовании тонкого вертикального BoxView, который заполняет высоту ViewCell. Наложение в первой строке — это изображение окружности. Здесь нет ничего сверхъестественного.
Сейчас можно заметить, что в нем используется ValueConverter для свойства IsVisible, что своего рода хитрость, которая нужна для того, чтобы линия не отображалась в последней строке. Наш объект модели (который, вероятно, будет ViewModel в реальном приложении) обладает свойством IsLast, в котором установлено значение true для последней строки. И кроме того, у нас есть NotBooleanConverter с присвоенным знанием IsVisible у линии, так что линия не отображается в последней строке. Кажется, получилось слегка неказисто, но ничего лучшего ко мне в голову на этот раз не пришло.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | <ListView.ItemTemplate> <DataTemplate> <ViewCell> <Grid ColumnSpacing="0" RowSpacing="0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="100" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Label HorizontalOptions="Center" Style="{StaticResource ClassTimeLabel}" Text="{Binding ClassTime, StringFormat='{0:H:mm}'}" /> <Label Grid.Column="2" Margin="20,0" Style="{StaticResource ClassNameLabel}" Text="{Binding ClassName}" /> <Label Grid.Row="1" Grid.Column="2" Margin="20,0" Style="{StaticResource ClassInstructorLabel}" Text="{Binding Instructor}" /> <BoxView Grid.RowSpan="2" Grid.Column="1" BackgroundColor="{StaticResource TimelineColor}" HorizontalOptions="Center" IsVisible="{Binding IsLast, Converter={local:NotBooleanConverter}}" VerticalOptions="Fill" WidthRequest="3" /> <Image Grid.Column="1" Source="Bullet.png" /> </Grid> </ViewCell> </DataTemplate> </ListView.ItemTemplate> |
Подведение итогов
Таким образом, при помощи ListView мы получили простую временную шкалу. И она отлично работает.
Ниже приведены ссылки, перейдя по которым можно получить дополнительные сведения о некоторых методах:
Как бы сказал некто с YouTube: Напишите в комментариях, понравился ли Вам этот материал: 🙂 Кроме того, если Вам известны какие-либо макеты, о которых может быть интересно рассказать непременно сообщите мне о них.
И да, Вы можете забрать полный код проекта на https://github.com/kphillpotts/XamarinFormsLayoutChallenges
Кроме того, ознакомьтесь с некоторыми другими макетами в Xamarin.Forms Layout Challenges.
Счастливого макета!
Источник: KymPhillpotts.com
Написать ответ