Fal*_*lko 55 android listview ios xamarin xamarin.forms
使用Xamarin.Forms,如何定义所选/点击的ListView项目的高亮/背景颜色?
(我的列表有黑色背景和白色文字颜色,因此iOS上的默认高亮颜色太亮了.相比之下,在Android上根本没有突出显示 - 直到细微的水平灰线.)
示例:(左:iOS,右:Android;按"Barn2"时)

小智 83
在Android中,只需在Resources\Value下编辑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>
Run Code Online (Sandbox Code Playgroud)
小智 63
看起来实际上有一种跨平台的方式可以在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) )
};
Run Code Online (Sandbox Code Playgroud)
您的自定义模型可能如下所示:
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 );
}
}
}
Run Code Online (Sandbox Code Playgroud)
那么对于你的ItemTemplate,你需要一个像这样的自定义单元类:
public class MyCell : ViewCell
{
public MyCell() : base()
{
RelativeLayout layout = new RelativeLayout();
layout.SetBinding( Layout.BackgroundColorProperty, new Binding( "BackgroundColor" ) );
View = layout;
}
}
Run Code Online (Sandbox Code Playgroud)
然后在ItemSelected事件处理程序中,执行以下操作.请注意,"已选择"是用于跟踪当前所选项目的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 );
}
Run Code Online (Sandbox Code Playgroud)
我有来自iOS和Android的屏幕截图,如果有人想让我达到10分,那么我可以实际发布它们:)
Fal*_*lko 27
解:
在自定义内,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;
}
Run Code Online (Sandbox Code Playgroud)
结果:

注意:
使用Xamarin.Forms,创建一个新的 UIView而不仅仅是设置当前颜色的背景颜色似乎很重要.
解:
我在Android上找到的解决方案有点复杂:
ViewCellBackground.xml在Resources> drawable文件夹中创建一个新的drawable :
<?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>
Run Code Online (Sandbox Code Playgroud)
它为默认状态和UI元素的"按下"状态定义了具有不同颜色的实体形状.
使用了一个继承类View你的ViewCell,例如:
public class TouchableStackLayout: StackLayout
{
}
Run Code Online (Sandbox Code Playgroud)为此类实现自定义渲染器设置后台资源:
public class ElementRenderer: VisualElementRenderer<Xamarin.Forms.View>
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e)
{
SetBackgroundResource(Resource.Drawable.ViewCellBackground);
base.OnElementChanged(e);
}
}
Run Code Online (Sandbox Code Playgroud)结果:

Ada*_*ley 12
我有一个类似的过程,完全跨平台,但我自己跟踪选择状态,我在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>
Run Code Online (Sandbox Code Playgroud)
然后在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;
};
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我只是将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
}
}
Run Code Online (Sandbox Code Playgroud)
小智 10
我有同样的问题,我通过为iOS创建自定义渲染器来解决它,正如Falko建议的那样,但是,我避免了Android的样式修改,我想出了一种方法来为Android使用自定义渲染器.
对于android视图单元格来说,所选标志总是假的,这是一种时髦的方式,这就是为什么我必须创建一个新的私有属性来跟踪它.但除此之外,如果您想为两个平台使用自定义渲染器,我认为这遵循更合适的模式.在我的情况下,我为TextCell做了它,但我相信它对其他CellView应用相同的方式.
Xamarin表格
using 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); }
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
要更改selected的颜色ViewCell,有一个简单的过程无需使用自定义渲染器。使Tapped您的事件ViewCell如下
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell Tapped="ViewCell_Tapped">
<Label Text="{Binding StudentName}" TextColor="Black" />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
Run Code Online (Sandbox Code Playgroud)
在您的ContentPage或.cs文件中,实现事件
private void ViewCell_Tapped(object sender, System.EventArgs e)
{
if(lastCell!=null)
lastCell.View.BackgroundColor = Color.Transparent;
var viewCell = (ViewCell)sender;
if (viewCell.View != null)
{
viewCell.View.BackgroundColor = Color.Red;
lastCell = viewCell;
}
}
Run Code Online (Sandbox Code Playgroud)
像这样lastCell在您的顶部声明ContentPageViewCell lastCell;
这是纯粹的跨平台和简洁的方式:
1)定义触发动作
namespace CustomTriggers {
public class DeselectListViewItemAction:TriggerAction<ListView> {
protected override void Invoke(ListView sender) {
sender.SelectedItem = null;
}
}
}
Run Code Online (Sandbox Code Playgroud)
2)将上述类实例应用于XAML中的EventTrigger操作,如下所示
<ListView x:Name="YourListView" ItemsSource="{Binding ViewModelItems}">
<ListView.Triggers>
<EventTrigger Event="ItemSelected">
<customTriggers:DeselectListViewItemAction></customTriggers:DeselectListViewItemAction>
</EventTrigger>
</ListView.Triggers>
</ListView>
Run Code Online (Sandbox Code Playgroud)
别忘了添加 xmlns:customTriggers="clr-namespace:CustomTriggers;assembly=ProjectAssembly"
注意:由于您的所有项目均未处于选定模式,因此不会在任一平台上应用选择样式.
仅适用于Android
添加您的自定义主题
<item name="android:colorActivatedHighlight">@android:color/transparent</item>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
88074 次 |
| 最近记录: |