2016-08-03 132 views
0

我有自定义条目,我想知道它什么时候聚焦,但它永远不会发生。我试图在自定义android类中捕获它,并在xaml事件聚焦,但它什么也没做。 我也有过这个问题,但没有解决它。 这是一堂课。评论块中的事件。聚焦或OnFocuseChange事件不会触发

using Android.Support.Design.Widget; 
using Android.Text; 
using Android.Views; 
using Android.Views.InputMethods; 
using GitRemote.CustomClasses; 
using GitRemote.Droid.DependencyServices; 
using GitRemote.Droid.Renderers; 
using GitRemote.ViewModels; 
using System.ComponentModel; 
using Xamarin.Forms; 
using Xamarin.Forms.Platform.Android; 
using Color = Xamarin.Forms.Color; 
using TextChangedEventArgs = Android.Text.TextChangedEventArgs; 
using View = Android.Views.View; 

[assembly: ExportRenderer(typeof(MaterialEntry), typeof(MaterialEntryRendererDroid))] 

namespace GitRemote.Droid.Renderers 
{ 
public class MaterialEntryRendererDroid : Xamarin.Forms.Platform.Android.AppCompat.ViewRenderer<Entry, View> 
{ 
private TextInputLayout _nativeView; 

    private TextInputLayout NativeView => _nativeView ?? (_nativeView = InitializeNativeView()); 

    protected override void OnElementChanged(ElementChangedEventArgs<Entry> e) 
    { 
     base.OnElementChanged(e); 



     if (e.OldElement != null) return; 

     // MaterialEntry Render Staff 
     #region 
     var ctrl = CreateNativeControl(); 
     SetNativeControl(ctrl); 

     SetText(); 
     SetHintText(); 
     SetBackgroundColor(); 
     SetTextColor(); 
     SetIsPassword(); 
     #endregion 

     if (Control != null) 
      switch (e.NewElement.ClassId) 
      { 
       case "LoginEntry": 
        ViewSaver.SaveLoginView(Control); 
        //Element.Focused += (sender, args) => 
        //{ 
        // ViewSaver.LastView = "LoginEntry"; 
        //}; 
        break; 

       case "PasswordEntry": 
        SetSendButtonAction(); 
        ViewSaver.SavePasswordView(Control); 

        //Element.Focused += (sender, args) => 
        //{ 
        // ViewSaver.LastView = "PasswordEntry"; 
        //}; 
        break; 

      } 
    } 

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     base.OnElementPropertyChanged(sender, e); 

     if (e.PropertyName == Entry.PlaceholderProperty.PropertyName) 
     { 
      SetHintText(); 
     } 

     if (e.PropertyName == Entry.TextColorProperty.PropertyName) 
     { 
      SetTextColor(); 
     } 

     if (e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName) 
     { 
      SetBackgroundColor(); 
     } 

     if (e.PropertyName == Entry.IsPasswordProperty.PropertyName) 
     { 
      SetIsPassword(); 
     } 

     if (e.PropertyName == Entry.TextProperty.PropertyName) 
     { 
      SetText(); 
     } 

    } 

    private void EditTextOnTextChanged(object sender, TextChangedEventArgs textChangedEventArgs) 
    { 
     Element.Text = textChangedEventArgs.Text.ToString(); 
     NativeView.EditText.SetSelection(Element.Text.Length); 
    } 

    private void SetText() 
    { 
     NativeView.EditText.Text = Element.Text; 
    } 

    private void SetIsPassword() 
    { 
     NativeView.EditText.InputType = Element.IsPassword 
      ? InputTypes.TextVariationPassword | InputTypes.ClassText 
      : InputTypes.TextVariationVisiblePassword; 
    } 

    public void SetBackgroundColor() 
    { 
     NativeView.SetBackgroundColor(Element.BackgroundColor.ToAndroid()); 
    } 

    private void SetHintText() 
    { 
     NativeView.Hint = Element.Placeholder; 
    } 

    private void SetTextColor() 
    { 
     if (Element.TextColor == Color.Default) 
      NativeView.EditText.SetTextColor(NativeView.EditText.TextColors); 
     else 
      NativeView.EditText.SetTextColor(Element.TextColor.ToAndroid()); 
    } 

    private TextInputLayout InitializeNativeView() 
    { 
     var view = FindViewById<TextInputLayout>(Resource.Id.textInputLayout); 
     view.EditText.TextChanged += EditTextOnTextChanged; 
     return view; 
    } 

    protected override View CreateNativeControl() 
    { 
     return LayoutInflater.From(Context).Inflate(Resource.Layout.TextInputLayout, null); 
    } 

    /// <summary> 
    /// If Action of our entry is Send than call method from Portable 
    /// </summary> 
    private void SetSendButtonAction() 
    { 
     NativeView.EditText.EditorAction += (sender, e) => 
     { 
      if (e.ActionId == ImeAction.Send) 
      { 
       ((LoginingPageViewModel)Element.BindingContext).OnLogInTapped(); 
      } 
      else 
       e.Handled = false; 
     }; 
    } 


} 
} 

回答

0

我用:

private void EditTextOnFocusChanged(object sender, FocusChangeEventArgs focusChangedEventArgs) 
    { 
     if (focusChangedEventArgs.HasFocus) 
      ViewSaver.SetLastView(Element.ClassId); 
    } 


view.EditText.FocusChange += EditTextOnFocusChanged; 

和它的作品。

0

我看你想实现的,如果我'对你试图实现一个谷歌的材料设计像Xamarin.Forms进入什么。让我们看看另一种方法;

第一步:在PCL项目中创建一个类

public class CustomEntry : Entry 
    { 

    } 

第二步:在App.xaml中

<ControlTemplate x:Key="MyControlTemplate"> 
    <Grid> 
     <Grid.RowDefinitions> 
     <RowDefinition Height="Auto"/> 
     <RowDefinition Height="Auto"/> 
     </Grid.RowDefinitions> 
     <controls:CustomEntry x:Name="myEntry" Text="{TemplateBinding Text, Mode=TwoWay}" HorizontalOptions="FillAndExpand" HorizontalTextAlignment="Start" IsPassword="{TemplateBinding IsPassword}" MinimumHeightRequest="25"/> 
     <BoxView Grid.Row="1" BackgroundColor="#D2D2D2" HeightRequest="1" HorizontalOptions="FillAndExpand" VerticalOptions="Start"> 
     <BoxView.Triggers> 
      <DataTrigger TargetType="BoxView" Binding="{Binding Source={x:Reference myEntry}, Path=IsFocused}" Value="true"> 
      <Setter Property="BackgroundColor" Value="Black" /> 
      <Setter Property="HeightRequest" Value="2"/> 
      </DataTrigger> 
     </BoxView.Triggers> 
     </BoxView> 
    </Grid> 
    </ControlTemplate> 

第3步创建控件模板:创建一个超材料设计的入门级

public class MyMaterialDesignEntry : ContentView, INotifyPropertyChanged 
    { 
     public static readonly BindableProperty TextProperty = 
     BindableProperty.Create("Text", typeof(string), typeof(ContentPage), ""); 
     public static readonly BindableProperty IsPasswordProperty = 
     BindableProperty.Create("IsPassword", typeof(bool), typeof(ContentPage), false); 

     public string Text 
     { 
      get { return (string)GetValue(TextProperty); } 
      set { SetValue(TextProperty, (string)value); } 
     }  

     public bool IsPassword => (bool)GetValue(IsPasswordProperty); 

     public MyMaterialDesignEntry() 
     { 
      ControlTemplate = (ControlTemplate)Application.Current.Resources.FirstOrDefault(x => x.Key == "MyControlTemplate").Value; 
     }  
    } 

步骤4:在xaml中使用您的超级材料设计条目

<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand"> 
      <Label Text="Login"/> 
      <controls:MyMaterialDesignEntry Text="{Binding Login, Mode=TwoWay}"/> 
      </StackLayout> 

不要忘记将适当的名称空间添加到您的页面xaml。无论如何,它会告诉你。

祝你们所有的人:d

+0

感谢您的工作你做了什么,但我拥有了一切,它的工作原理。问题是另一个。我想知道我的习惯何时有重点,什么时候失去它。所以我在xaml中使用了“Focused”,而在Android项目中使用了OnFocusChange等其他事件。但它永远不会开火。 事情是在这一行: //Element.Focused + =(sender,args)=> // { // ViewSaver.LastView =“LoginEntry”; //}; –

+0

首先你的代码很臭,你应该阅读关于SOLID和OOP。如果您想在IsFocused属性更改时引发另一个事件,请转到https://developer.xamarin.com/guides/xamarin-forms/working-with/triggers/并检查enteractions和exitactions部分。您可以将这些技巧与我上面发送的代码一起使用。 –

+0

请回答问题,不要说我已经知道的和另外一些事情,如“臭”。您向我展示了自定义条目的标准化和简单实现,没有“自定义”实际情况。我有一些代码正在做的事情,所以它有些相似。所以在说点什么之前,请尽量弄清楚它。 它没有着火,请理解它。 –