Intereting Posts
Эффект пульсации для просмотра леденцов Android получает RESULT_CANCELED, когда я специально добавляю RESULT_OK Можно ли запускать приложения для Linux в Android? Фоновая привязка: исправлено не работает на android / mobile EditText с мягкой клавиатурой и кнопкой «Назад» Определить тип данных столбца в SQLite Отключить уведомления приложения программно на Android Robotium. В наборе тестов каждый следующий тест зависит от предыдущего теста Разница между OnlyOnRanToCompletion и NotOnFaulted? Google Play Game Services Multi-Player Устройство Изменение ориентации выдает пользователя из комнаты Есть ли рекомендуемая стратегия для выпуска бета-версии приложения для ограниченного числа пользователей через Android Market? OSX Yosemite, ADB и USB должны постоянно подключаться к устройству Можно ли отключить все радиокнопки в приложении для Android? Удалите все неиспользуемые классы, методы из проекта Android Studio Оценка MapboxGLManager.mapStyles

Xamarin.Forms ListView: установка цвета подсветки элемента

Используя Xamarin.Forms , как я могу определить цвет выделения / фона для выбранного элемента ListView Listed?

(Мой список имеет черный фон и белый цвет текста, поэтому цвет подсветки по умолчанию на iOS слишком яркий. Напротив, на Android нет подсветки вообще – до тонкой горизонтальной серой линии.)

Пример: (слева: iOS, справа: Android, при нажатии «Barn2»)

Solutions Collecting From Web of "Xamarin.Forms ListView: установка цвета подсветки элемента"

Похоже, что есть кросс-платформенный способ сделать это, который работает как на iOS, так и на Android (не уверен в Windows). Он использует только привязку и не требует специальных рендерингов (что кажется редким). Это мусор большого количества поисковых систем, поэтому благодаря любому, кого я мог бы заимствовать …

Я предполагаю ViewCells, но это должно работать и для ячеек Text или Image. Я включаю только соответствующий код здесь, кроме обычного текста, изображения и т. Д.

На вашей странице сделайте что-то вроде этого:

MyModel model1 = new MyModel(); MyModel model2 = new MyModel(); ListView list = new ListView { ItemsSource = new List<MyModel> { model1, model2 }; ItemTemplate = new DataTemplate( typeof(MyCell) ) }; 

Ваша пользовательская модель может выглядеть примерно так:

 public class MyModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private Color _backgroundColor; public Color BackgroundColor { get { return _backgroundColor; } set { _backgroundColor = value; if ( PropertyChanged != null ) { PropertyChanged( this, new PropertyChangedEventArgs( "BackgroundColor" ) ); } } } public void SetColors( bool isSelected ) { if ( isSelected ) { BackgroundColor = Color.FromRgb( 0.20, 0.20, 1.0 ); } else { BackgroundColor = Color.FromRgb( 0.95, 0.95, 0.95 ); } } } 

Затем для вашего ItemTemplate вам понадобится собственный класс ячеек:

 public class MyCell : ViewCell { public MyCell() : base() { RelativeLayout layout = new RelativeLayout(); layout.SetBinding( Layout.BackgroundColorProperty, new Binding( "BackgroundColor" ) ); View = layout; } } 

Затем в обработчике событий ItemSelected сделайте следующее. Обратите внимание, что «selected» – это экземпляр MyModel, используемый для отслеживания выбранного в данный момент элемента. Я только показываю цвет фона здесь, но я также использую эту технику для обратного выделения цвета текста и деталей текста.

 private void ItemSelected( object sender, ItemTappedEventArgs args ) { // Deselect previous if ( selected != null ) { selected.SetColors( false ); } // Select new selected = (list.SelectedItem as MyModel); selected.SetColors( true ); } 

У меня есть скриншоты из iOS и Android, если кто-то хочет поднять меня до 10 очков, чтобы я мог опубликовать их 🙂

В Android просто отредактируйте файл Style.xml в разделе Ресурсы \ Значение, добавив следующее:

 <resources> <style name="MyTheme" parent="android:style/Theme.Material.Light.DarkActionBar"> <item name="android:colorPressedHighlight">@color/ListViewSelected</item> <item name="android:colorLongPressedHighlight">@color/ListViewHighlighted</item> <item name="android:colorFocusedHighlight">@color/ListViewSelected</item> <item name="android:colorActivatedHighlight">@color/ListViewSelected</item> <item name="android:activatedBackgroundIndicator">@color/ListViewSelected</item> </style> <color name="ListViewSelected">#96BCE3</color> <color name="ListViewHighlighted">#E39696</color> </resources> 

IOS

Решение:

В пользовательском ViewCellRenderer вы можете установить SelectedBackgroundView . Просто создайте новый UIView с цветом фона по вашему выбору, и вы настроены.

 public override UITableViewCell GetCell(Cell item, UITableView tv) { var cell = base.GetCell(item, tv); cell.SelectedBackgroundView = new UIView { BackgroundColor = UIColor.DarkGray, }; return cell; } 

Результат:

Заметка:

С Xamarin.Forms, кажется, важно создать новый UIView а не просто устанавливать цвет фона текущего.


Android

Решение:

Решение, которое я нашел на Android, немного сложнее:

  1. Создайте новый ViewCellBackground.xml в папке Resources >:

     <?xml version="1.0" encoding="UTF-8" ?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" > <shape android:shape="rectangle"> <solid android:color="#333333" /> </shape> </item> <item> <shape android:shape="rectangle"> <solid android:color="#000000" /> </shape> </item> </selector> 

    Он определяет сплошные формы с разными цветами для состояния по умолчанию и «нажатого» состояния элемента пользовательского интерфейса.

  2. Используйте унаследованный класс для представления вашего ViewCell , например:

     public class TouchableStackLayout: StackLayout { } 
  3. Внедрите собственный рендер для этого класса, задав фоновый ресурс:

     public class ElementRenderer: VisualElementRenderer<Xamarin.Forms.View> { protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e) { SetBackgroundResource(Resource.Drawable.ViewCellBackground); base.OnElementChanged(e); } } 

Результат:

У меня есть аналогичный процесс, полностью перекрестная платформа, однако я отслеживаю статус выбора самостоятельно, и я сделал это в XAML.

  <ListView x:Name="ListView" ItemsSource="{Binding ListSource}" RowHeight="50"> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <ViewCell.View> <ContentView Padding="10" BackgroundColor="{Binding BackgroundColor}"> <Label Text="{Binding Name}" HorizontalOptions="Center" TextColor="White" /> </ContentView> </ViewCell.View> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView> 

Затем в событии ItemTapped

  ListView.ItemTapped += async (s, e) => { var list = ListSource; var listItem = list.First(c => c.Id == ((ListItem)e.Item).Id); listItem.Selected = !listItem.Selected; SelectListSource = list; ListView.SelectedItem = null; }; 

Как вы можете видеть, я просто установил для ListView.SelectedItem значение null, чтобы удалить любой из стилей выбора конкретной платформы, которые вступают в игру.

В моей модели у меня есть

  private Boolean _selected; public Boolean Selected { get { return _selected; } set { _selected = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("BackgroundColor")); } } public Color BackgroundColor { get { if (Selected) return Color.Black; else return Color.Blue } } 

Чтобы установить цвет выделенного элемента, вам нужно установить цвет cell.SelectionStyle в iOS.

В этом примере нужно задать прозрачность цвета элемента с пунктиром.

Если вы хотите, вы можете изменить его с другими цветами из UITableViewCellSelectionStyle . Это должно быть написано в платформенном проекте iOS, создав новый визуализатор Custom ListView в вашем проекте Forms.

 public class CustomListViewRenderer : ListViewRenderer { protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) { base.OnElementPropertyChanged(sender, e); if (Control == null) { return; } if (e.PropertyName == "ItemsSource") { foreach (var cell in Control.VisibleCells) { cell.SelectionStyle = UITableViewCellSelectionStyle.None; } } } } 

Для android вы можете добавить этот стиль в свои значения / styles.xml

 <style name="ListViewStyle.Light" parent="android:style/Widget.ListView"> <item name="android:listSelector">@android:color/transparent</item> <item name="android:cacheColorHint">@android:color/transparent</item> </style> 

У меня была эта же проблема, и я решил ее также, создав собственный рендерер для iOS, как предлагает Falko, однако я избегал модификации стилей для Android, я также выяснил способ использования специального рендеринга для Android.

Это довольно забавно, так как выбранный флаг всегда является ложным для ячейки вида android, поэтому мне пришлось создать новое частное свойство для его отслеживания. Но, кроме того, я думаю, что это следует за более подходящим шаблоном, если вы хотите использовать собственные рендереры для обеих платформ. В моем случае я сделал это для TextCell, но я считаю, что он применяется одинаково для других CellView.

Xamarin Forms

 public class CustomTextCell : TextCell { /// <summary> /// The SelectedBackgroundColor property. /// </summary> public static readonly BindableProperty SelectedBackgroundColorProperty = BindableProperty.Create("SelectedBackgroundColor", typeof(Color), typeof(CustomTextCell), Color.Default); /// <summary> /// Gets or sets the SelectedBackgroundColor. /// </summary> public Color SelectedBackgroundColor { get { return (Color)GetValue(SelectedBackgroundColorProperty); } set { SetValue(SelectedBackgroundColorProperty, value); } } } 

IOS

 public class CustomTextCellRenderer : TextCellRenderer { public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv) { var cell = base.GetCell(item, reusableCell, tv); var view = item as CustomTextCell; cell.SelectedBackgroundView = new UIView { BackgroundColor = view.SelectedBackgroundColor.ToUIColor(), }; return cell; } } 

Android

 public class CustomTextCellRenderer : TextCellRenderer { private Android.Views.View cellCore; private Drawable unselectedBackground; private bool selected; protected override Android.Views.View GetCellCore(Cell item, Android.Views.View convertView, ViewGroup parent, Context context) { cellCore = base.GetCellCore(item, convertView, parent, context); // Save original background to rollback to it when not selected, // We assume that no cells will be selected on creation. selected = false; unselectedBackground = cellCore.Background; return cellCore; } protected override void OnCellPropertyChanged(object sender, PropertyChangedEventArgs args) { base.OnCellPropertyChanged(sender, args); if (args.PropertyName == "IsSelected") { // I had to create a property to track the selection because cellCore.Selected is always false. // Toggle selection selected = !selected; if (selected) { var customTextCell = sender as CustomTextCell; cellCore.SetBackgroundColor(customTextCell.SelectedBackgroundColor.ToAndroid()); } else { cellCore.SetBackground(unselectedBackground); } } } } 

Вот чисто кросс-платформа и аккуратный способ:

1) Определить действие триггера

 namespace CustomTriggers { public class DeselectListViewItemAction:TriggerAction<ListView> { protected override void Invoke(ListView sender) { sender.SelectedItem = null; } } } 

2) Применить вышеупомянутый экземпляр класса как действие EventTrigger в XAML, как показано ниже

  <ListView x:Name="YourListView" ItemsSource="{Binding ViewModelItems}"> <ListView.Triggers> <EventTrigger Event="ItemSelected"> <customTriggers:DeselectListViewItemAction></customTriggers:DeselectListViewItemAction> </EventTrigger> </ListView.Triggers> </ListView> 

Не забудьте добавить xmlns:customTriggers="clr-namespace:CustomTriggers;assembly=ProjectAssembly"

Примечание. Поскольку ни один из ваших элементов не выбран в выбранном режиме, стилизация выбора не будет применена ни на одной из платформ.