android - 以xamarin形式在 ListView 内随机触发的条目控制焦点取消焦点事件

标签 android xamarin xamarin.ios xamarin.android xamarin.forms

在我的 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/

相关文章:

java - 无法从抽屉导航中的 Fragment/FragmentActivity 打开 FragmentActivity

android - AWS SNS Android GCM - InvalidPlatformToken

c# - 处理全局异常机器人 | iOS

Azure 通知中心 : What is Success and Failure Property in NotificationOutcome

ios - 在 DialogViewController 中滚动破坏了单元格点击事件

ios - Xamarin iOS 链接器导致 AutoMapper 问题

ios - 尽管垂直对齐设置为中心,但 UITextField 是第一响应者时的文本要么被剪裁,要么出现在内容 View 的底部

android - 我无法在 macOS Sierra 上安装英特尔 HAXM

Android 使用 JNI 而不使用静态变量

android - 任务 ':dexDebug' 执行失败