如何为Xamarin.Forms中ListView的ViewCell添加Material Design涟漪效果?
嘿,我来帮你搞定这个Xamarin.Forms里ViewCell的Material涟漪效果问题,顺便解决那个烦人的MissingMethodException报错~
你遇到的方法找不到异常,本质是旧版本Xamarin.Forms对Material Visual的支持有兼容性bug——你的VS2019 16.1.3对应的Xamarin.Forms版本大概率是4.2.x左右,这个版本的Material Visual还不够稳定。
步骤1:升级Xamarin.Forms版本
打开项目的NuGet包管理器,找到Xamarin.Forms,把它升级到4.5.0.617及以上的稳定版本(越新越好,最新稳定版修复了大量Material相关bug)。
步骤2:启用Material Visual
有两种启用方式,推荐全局启用:
全局启用(全应用生效)
在App.xaml的Application标签上添加Visual="Material",整个应用都会采用Material Design风格:
<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="YourAppName.App" Visual="Material"> <!-- 原有内容 --> </Application>
局部启用(仅当前ListView生效)
如果只想让这个ListView的ViewCell有涟漪效果,直接在ListView或ViewCell上添加属性:
<ListView x:Name="ItemsListView" ItemsSource="{Binding Items}" VerticalOptions="FillAndExpand" HasUnevenRows="true" RefreshCommand="{Binding LoadItemsCommand}" IsPullToRefreshEnabled="true" IsRefreshing="{Binding IsBusy, Mode=OneWay}" CachingStrategy="RecycleElement" ItemSelected="OnItemSelected" Visual="Material"> <!-- 原有ItemTemplate内容 --> <ListView.ItemTemplate> <DataTemplate> <ViewCell Visual="Material"> <StackLayout Padding="10"> <Label Text="{Binding Text}" d:Text="{Binding .}" LineBreakMode="NoWrap" FontSize="16" /> <Label Text="{Binding Description}" d:Text="Item description" LineBreakMode="NoWrap" FontSize="13" /> </StackLayout> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView>
步骤3:调整样式(可选)
默认的Material风格已经自带涟漪效果,如果你想替换原来的橙色高亮,可以给ViewCell设置背景色:
<ViewCell Visual="Material" BackgroundColor="White"> <!-- 原有StackLayout内容 --> </ViewCell>
如果暂时不想升级Xamarin.Forms,可以通过Android原生渲染器手动添加涟漪效果:
步骤1:在共享项目创建自定义ViewCell
using Xamarin.Forms; namespace YourAppName { public class RippleViewCell : ViewCell { } }
步骤2:在Android项目编写渲染器
创建RippleViewCellRenderer类,继承自ViewCellRenderer,给原生View添加涟漪效果:
using Android.Content; using Android.Graphics.Drawables; using YourAppName; using YourAppName.Droid; using Xamarin.Forms; using Xamarin.Forms.Platform.Android; [assembly: ExportRenderer(typeof(RippleViewCell), typeof(RippleViewCellRenderer))] namespace YourAppName.Droid { public class RippleViewCellRenderer : ViewCellRenderer { protected override Android.Views.View GetCellCore(Cell item, Android.Views.View convertView, ViewGroup parent, Context context) { var cell = base.GetCellCore(item, convertView, parent, context); // 创建半透明黑色的涟漪效果 var rippleDrawable = new RippleDrawable(ColorStateList.ValueOf(Android.Graphics.Color.ParseColor("#80000000")), null, null); cell.Background = rippleDrawable; // 去掉默认的橙色高亮背景 cell.SetBackgroundColor(Android.Graphics.Color.Transparent); return cell; } } }
步骤3:替换XAML中的ViewCell
在页面XAML中引入命名空间,并用自定义的RippleViewCell替换原有ViewCell:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:YourAppName" x:Class="YourAppName.ItemsPage"> <!-- 原有内容 --> <ListView x:Name="ItemsListView" ...> <ListView.ItemTemplate> <DataTemplate> <local:RippleViewCell> <StackLayout Padding="10"> <Label Text="{Binding Text}" d:Text="{Binding .}" LineBreakMode="NoWrap" FontSize="16" /> <Label Text="{Binding Description}" d:Text="Item description" LineBreakMode="NoWrap" FontSize="13" /> </StackLayout> </local:RippleViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView> </ContentPage>
两种方案都能实现你想要的Material涟漪效果,推荐第一种,升级版本后还能获得更多Material Design的特性和bug修复。
内容的提问来源于stack exchange,提问作者Junelilly

