Xamarin.Forms CollectionView Android端选中项自定义高亮失效问题
Xamarin.Forms CollectionView 安卓端自定义选中高亮异常问题
问题现象
- 为CollectionView的选中项设置差异化的自定义高亮背景色时,iOS平台运行正常
- Android平台存在异常表现:始终默认第一项为选中状态,点击其他条目时无法正常触发对应高亮效果
排查结论
经定位,问题根源是挂载在条目Grid上的GestureRecognizers:移除GestureRecognizers后,选中高亮行为完全符合预期,添加GestureRecognizers后则丢失正常高亮逻辑。
已验证临时方案
- 临时方案1:将Grid包裹在SwipeView内部时可恢复正常高亮效果,但当CollectionView包含超过100个条目时,问题仍会复现
- 临时方案2:在原第一层Grid内部新增第二个子Grid,将所有GestureRecognizers事件绑定到新增的子Grid上,即可平稳实现预期效果,该方案对任意条目数量的CollectionView均可良好生效
相关代码定义
主题文件定义的条目样式
<Style TargetType="Grid" x:Key="ItemTemplateGrid"> <Setter Property="VisualStateManager.VisualStateGroups"> <VisualStateGroupList> <VisualStateGroup> <VisualState Name="Normal"/> <VisualState Name="Selected"> <VisualState.Setters> <Setter Property="BackgroundColor" Value="{AppThemeBinding Dark={StaticResource BackgroundSecondaryColorDark}, Light={StaticResource BackgroundSecondaryColorLight}}"/> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateGroupList> </Setter> </Style>
页面条目模板定义
<DataTemplate x:Key="AndroidAyaItemTemplate"> <Grid RowDefinitions="*,Auto" Style="{DynamicResource ItemTemplateGrid}"> <Grid Grid.Row="0" RowDefinitions="Auto,Auto,Auto" RowSpacing="0" Padding="10"> <Label Grid.Row="0" LineBreakMode="WordWrap" IsVisible="{Binding BindingContext.ShowEnglishVerseNumber, Source={x:Reference MyPage}, Converter={StaticResource InverterBooleanConverter}}"> <Label.FormattedText> <FormattedString> <Span Text="{Binding ArabicText.Aya}" FontSize="{Binding BindingContext.ActiveArabicFont.FontSize, Source={x:Reference MyPage}}" FontFamily="{Binding BindingContext.ActiveArabicFont.FontPath, Source={x:Reference MyPage}}"/> <Span Text="{Binding ArabicText.ArabicAyaNumber, StringFormat='﴿{0}﴾'}" FontSize="{Binding BindingContext.ActiveArabicFont.FontSize, Source={x:Reference MyPage}}" FontFamily="Sherzad"></Span> </FormattedString> </Label.FormattedText> </Label> <Label Grid.Row="0" LineBreakMode="WordWrap" IsVisible="{Binding BindingContext.ShowEnglishVerseNumber, Source={x:Reference MyPage}}"> <Label.FormattedText> <FormattedString> <Span Text="{Binding ArabicText.Aya}" FontSize="{Binding BindingContext.ActiveArabicFont.FontSize, Source={x:Reference MyPage}}" FontFamily="{Binding BindingContext.ActiveArabicFont.FontPath, Source={x:Reference MyPage}}"/> <Span Text="﴿" FontSize="35" FontFamily="Sherzad"></Span> <Span Text="{Binding ArabicText.AyaNumber, Converter={StaticResource ZeroToEmptyConverter}}" FontSize="Small"></Span> <Span Text="﴾" FontSize="35" FontFamily="Sherzad"></Span> </FormattedString> </Label.FormattedText> </Label> <Label Grid.Row="1" LineBreakMode="WordWrap" HorizontalTextAlignment="Start" Margin="0,5,0,5" IsVisible="{Binding BindingContext.ShowTransliteration, Source={x:Reference MyPage}}" FontSize="{Binding BindingContext.TransliterationFontSize, Source={x:Reference MyPage}}" Text="{Binding ArabicText.Transliteration}" FlowDirection="LeftToRight"> </Label> <Label Grid.Row="2" LineBreakMode="WordWrap" HorizontalTextAlignment="Start" IsVisible ="{Binding BindingContext.TranslationVisible, Source={x:Reference MyPage}}" FontSize="{Binding BindingContext.ActiveTranslationFont.FontSize, Source={x:Reference MyPage}}" FontFamily="{Binding BindingContext.ActiveTranslationFont.FontPath, Source={x:Reference MyPage}}" Text="{Binding AyaTranslation}" FlowDirection="{Binding BindingContext.ActiveTranslationLanguage.FlowDirection, Source={x:Reference MyPage}}"/> </Grid> <BoxView Grid.Row="1" Style="{DynamicResource HLine}" IsVisible="{Binding BindingContext.ShowHorizentalLine, Source={x:Reference MyPage}}"/> <Grid.GestureRecognizers> <TapGestureRecognizer NumberOfTapsRequired="2" Command="{Binding BindingContext.ShareAyaCommand,Source={x:Reference itemView}}" CommandParameter="{Binding .}"/> <SwipeGestureRecognizer Direction="Right" Command="{Binding BindingContext.NextChapterCommand, Source={x:Reference MyPage}}"/> <SwipeGestureRecognizer Direction="Left" Command="{Binding BindingContext.PreviousChapterCommand, Source={x:Reference MyPage}}"/> </Grid.GestureRecognizers> </Grid> </DataTemplate>
CollectionView控件定义
<CollectionView Grid.Row="0" ItemsSource="{Binding ArabicListText}" SelectedItem="{Binding SelectedAya}" SelectionMode="Single" FlowDirection="RightToLeft" ItemTemplate="{StaticResource AndroidAyaItemTemplate}" x:Name="itemView"> <CollectionView.ItemsLayout> <LinearItemsLayout Orientation="Vertical" ItemSpacing="5"/> </CollectionView.ItemsLayout> </CollectionView>
补充验证结果
移除Grid上的ItemTemplateGrid样式后,所有条目均可正常响应选中高亮,但高亮颜色为操作系统默认颜色。
核心诉求
无需借助SwipeView或上述拆分嵌套Grid的临时方案,也能实现自定义的选中高亮逻辑
内容的提问来源于stack exchange,提问作者ARH
相关产品推荐
相关产品推荐

