2016-08-03 26 views
0

私はカスタムエントリを持っています。フォーカスしたタイミングを知りたいのですが、決して起こっていません。私はカスタムアンドロイドクラスでそれを捕まえようとしましたが、xamlイベントではFocusedでしたが、何もしませんでした。 私も前にこの問題を抱えていましたが、解決できませんでした。 ここにクラスがあります。コメントブロック内のイベント。フォーカスされたイベントまたは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

I'amは、右あなたがXamarin.Forms内のエントリのようなGoogleの材料設計を実現しようとしている場合、私は、あなたが達成しようとしているものを参照してください。別のアプローチを見てみましょう。

ステップ1:ステップ2

public class CustomEntry : Entry 
    { 

    } 

PCLプロジェクトでクラスを作成します。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

あなたの仕事に感謝しましたが、私はそれをすべて持っています。質問は別です。私はいつも私のカスタムenrtyが集中しているときとそれが失われたときを知りたい。だから、私はxamlで "Focused"を使用し、AndroidプロジェクトではOnFocusChangeのような別のイベントを使用しました。しかし、決して発火しません。 これは次の行にあります: //Element.Focused + =(送信者、引数)=> // { // ViewSaver.LastView = "LoginEntry"; //}; –

+0

まず、あなたのコードは非常に臭いです。あなたはSOLIDとOOPについて読むべきです。 IsFocusedプロパティが変更されたときに別のイベントを発生させたい場合は、https://developer.xamarin.com/guides/xamarin-forms/working-with/triggers/に行き、enteractionsとexitactionsセクションをチェックしてください。上記のコードでこれらのトリックを使うことができます。 –

+0

質問にお答えください。私がすでに知っていることと、「臭い」のようなことは言いません。あなたは私に、本当に何か「カスタム」なしで、カスタムエントリのすぐれた実装を見せてくれました。私はいくつかのコードが何をしているので、それはいくつかのcomlicatedです。だから、何かを言う前にそれを理解しようとしてください。 それは発火しませんので、ご了承ください。 –

関連する問題