在我的 xamarin 表单项目中,我有一个带有 ListView 的屏幕,其中包含 Entry 和其他控件的数量。
对于输入,我已经为 text_changed、focus 和 unfocus 事件定义了功能。并且条目有十进制键盘(只接受十进制)。
问题:每当我尝试输入数字时,预期的行为是触发 text_changed 但它也会触发 unfocus 和 focus 事件两次。
[输入text->text_changed->unfocus->focus->unfocus->focus]。因此,我在各个事件中编写的所有逻辑都被打乱并显示出奇怪的行为。
这个在 iOS 中按预期工作,仅在 Android 中显示此问题。
代码:
<DataTemplate x:Key="Numeric">
<ViewCell>
<ViewCell.View>
<StackLayout Padding="0">
<StackLayout Spacing="0" Padding="10">
<Grid ColumnSpacing="0" Padding="0" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<controls:CustomLabel Text="{Binding .Question}" Style="{StaticResource ListItemInspectionLabelStyleWordwrap}" HorizontalOptions="Start" VerticalOptions="Start" Grid.Row="0" Grid.Column="0" />
<controls:CustomEntry x:Name="InputEntry" IsEnabled="{Binding .CanRespond}" FontSize="12" TextChanged="OnNumericTextChanged" HeightRequest="50" Keyboard="Numeric" Focused="OnNumericFocus" Unfocused="OnNumericUnFocus" HorizontalOptions="FillAndExpand" VerticalOptions="End"
ClassId="{Binding .QuestionId}" Grid.Row="1" Grid.Column="0" />
<controls:ExtendedLabel x:Name="NumberHint" TextColor="#71797B" LineBreakMode="NoWrap" Text="{Binding NumericFieldTitle}" Style="{StaticResource ListItemInspectionLabelStyleWordwrap}"
HorizontalOptions="Start" VerticalOptions="Start" Grid.Row="2" Grid.Column="0" />
</Grid>
</StackLayout>
<BoxView Style="{StaticResource ListDividerStyle}" />
</StackLayout>
</ViewCell.View>
</ViewCell>
</DataTemplate>
对于 Entry,我已经为一些对齐编写了渲染器:
[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
namespace Inspect.Droid
{
public class CustomEntryRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (e.OldElement == null)
{
Control.SetBackgroundColor(global::Android.Graphics.Color.Rgb(230, 230, 230));
Control.SetTextColor(global::Android.Graphics.Color.Black);
var nativeEditText = (global::Android.Widget.EditText)Control;
nativeEditText.SetTextColor(Android.Graphics.Color.Black);
nativeEditText.SetBackgroundResource(Resource.Drawable.inspection_editor_background);
nativeEditText.SetPadding(30, 0, 0, 0);
nativeEditText.Gravity = Android.Views.GravityFlags.CenterVertical;
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
var nativeEditText = (global::Android.Widget.EditText)Control;
nativeEditText.SetPadding(30, 0, 0, 0);
nativeEditText.Gravity = Android.Views.GravityFlags.CenterVertical;
}
}
}
即使我看到很少有帖子报告相同的问题,但没有得到任何解决方案/解决方法。 xamarin bugzilla 中报告了同样的问题和 Selecting Entry Controls Within ViewCells Causes FocusChange Cycle 和其他link
由于我的要求仅适用于此事件,因此我没有其他方法可以实现它。请向我建议此实现的任何解决方案/解决方法或提示/链接。
谢谢
最佳答案
我通过使用 Forms 2.3.3.180 测试重新审视了您提到的焦点循环错误,据我所知,焦点循环来自 OnLayout()
being fired on the ListView .我不确定为什么叫它,但我觉得它可能与键盘出现有关。
但即使它被调用,位置和大小似乎也没有改变,这也得到了 changed
参数设置为 false 的支持。因此,您可以做的是创建自定义 ListView 渲染器并重写 OnLayout()
,以便在 changed == false
时不调用 base。
我确实在错误报告中的示例项目上尝试过这个,它似乎解决了这个问题。但是,作为免责声明,我会说我没有对其进行广泛测试,并且鉴于示例项目很简单,执行此操作可能会在您的应用程序中出现其他问题。
[assembly: ExportRenderer(typeof(EntryListView), typeof(EntryListViewRenderer))]
namespace ListViewCheck.Droid
{
public class EntryListViewRenderer: ListViewRenderer
{
protected override void OnLayout(bool changed, int l, int t, int r, int b)
{
if (changed)
base.OnLayout(changed, l, t, r, b);
}
}
}
关于android - 以xamarin形式在 ListView 内随机触发的条目控制焦点取消焦点事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42018962/