Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Xamarin.Forms Tip: Implement Show/Hide Password Using Effects

DZone's Guide to

Xamarin.Forms Tip: Implement Show/Hide Password Using Effects

Learn how to implement a Show/Hide password feature for your Xamarin.Forms mobile apps, for both your iOS and Android apps.

· Mobile Zone ·
Free Resource

While developing login pages, we usually get a requirement that there should be an icon in password entry to show/hide the password while entering it. While looking for a solution to this requirement, I found that most of the implementation is done using custom controls, whereas we can do this kind of small platform-specific customization using effects. Last year, I wrote this article about implementing custom fonts using effects, so I thought, let's try this also using effects.

Creating the Effect

  • Changes in PCL project:
  • Create a new class file named ‘ShowHidePassEffect’ and add the following code to it:

    public class ShowHidePassEffect: RoutingEffect {
     public string EntryText {
      get;
      set;
     }
     public ShowHidePassEffect(): base("Xamarin.ShowHidePassEffect") {}
    }

    In the above code, we are creating a custom effect where we are creating a new property named ‘EntryText’ to show the entered password text. The implementation of this effect will have to be written in Platform specific projects.

  • Changes in Android project:
  • In your Android project, create a new class file named ‘ShowHidePassEffect’ and add the following code to it:

    using Android.Text.Method;
    using Android.Views;
    using Android.Widget;
    using Xamarin.Forms;
    using Xamarin.Forms.Platform.Android;
    
    [assembly: ResolutionGroupName("Xamarin")]
    [assembly: ExportEffect(typeof(ShowHidePassEx.Droid.Effects.ShowHidePassEffect), "ShowHidePassEffect")]
    namespace ShowHidePassEx.Droid.Effects {
     public class ShowHidePassEffect: PlatformEffect {
    
    
      protected override void OnAttached() {
       ConfigureControl();
      }
    
      protected override void OnDetached() {}
    
      private void ConfigureControl() {
       EditText editText = ((EditText) Control);
       editText.SetCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, Resource.Drawable.ShowPass, 0);
       editText.SetOnTouchListener(new OnDrawableTouchListener());
    
      }
     }
    
     public class OnDrawableTouchListener: Java.Lang.Object, Android.Views.View.IOnTouchListener {
      public bool OnTouch(Android.Views.View v, MotionEvent e) {
       if (v is EditText && e.Action == MotionEventActions.Up) {
        EditText editText = (EditText) v;
        if (e.RawX >= (editText.Right - editText.GetCompoundDrawables()[2].Bounds.Width())) {
         if (editText.TransformationMethod == null) {
          editText.TransformationMethod = PasswordTransformationMethod.Instance;
          editText.SetCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, Resource.Drawable.ShowPass, 0);
         } else {
          editText.TransformationMethod = null;
          editText.SetCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, Resource.Drawable.HidePass, 0);
         }
    
         return true;
        }
       }
    
       return false;
      }
     }
    }

    In the above mentioned Android implementation of the effect, we are adding the code to create the control manually in the ‘OnDrawableTouchListener’ method, where we are adding the ShowPass and HidePass icons to the entry control, changing them on the basis of user touch action and attaching it on effect invocation, which will be fired when the effect is added to the control.

    Before writing this code, make sure that you have ShowPass and HidePass images in your Resources/Drawable folder of the Android project, like the following image :

    These images can be downloaded from internet or your project’s designer can provide it.

  • Changes in iOS project:
  • Similarly, in your iOS project create a new class file named ‘ShowHidePassEffect’ and add following code to it:

    using System;
    using ShowHidePassEx.iOS.Effects;
    using UIKit;
    using Xamarin.Forms;
    using Xamarin.Forms.Platform.iOS;
    
    
    [assembly: ResolutionGroupName("Xamarin")]
    [assembly: ExportEffect(typeof(ShowHidePassEffect), "ShowHidePassEffect")]
    namespace ShowHidePassEx.iOS.Effects {
     public class ShowHidePassEffect: PlatformEffect {
    
      protected override void OnAttached() {
       ConfigureControl();
      }
    
      protected override void OnDetached() {
    
      }
    
      private void ConfigureControl() {
       if (Control != null) {
        UITextField vUpdatedEntry = (UITextField) Control;
        var buttonRect = UIButton.FromType(UIButtonType.Custom);
        buttonRect.SetImage(new UIImage("ShowPass"), UIControlState.Normal);
        buttonRect.TouchUpInside += (object sender, EventArgs e1) => {
         if (vUpdatedEntry.SecureTextEntry) {
          vUpdatedEntry.SecureTextEntry = false;
          buttonRect.SetImage(new UIImage("HidePass"), UIControlState.Normal);
         } else {
          vUpdatedEntry.SecureTextEntry = true;
          buttonRect.SetImage(new UIImage("ShowPass"), UIControlState.Normal);
         }
        };
    
        vUpdatedEntry.ShouldChangeCharacters += (textField, range, replacementString) => {
         string text = vUpdatedEntry.Text;
         var result = text.Substring(0, (int) range.Location) + replacementString + text.Substring((int) range.Location + (int) range.Length);
         vUpdatedEntry.Text = result;
         return false;
        };
    
    
        buttonRect.Frame = new CoreGraphics.CGRect(10.0 f, 0.0 f, 15.0 f, 15.0 f);
        buttonRect.ContentMode = UIViewContentMode.Right;
    
        UIView paddingViewRight = new UIView(new System.Drawing.RectangleF(5.0 f, -5.0 f, 30.0 f, 18.0 f));
        paddingViewRight.Add(buttonRect);
        paddingViewRight.ContentMode = UIViewContentMode.BottomRight;
    
    
        vUpdatedEntry.LeftView = paddingViewRight;
        vUpdatedEntry.LeftViewMode = UITextFieldViewMode.Always;
    
        Control.Layer.CornerRadius = 4;
        Control.Layer.BorderColor = new CoreGraphics.CGColor(255, 255, 255);
        Control.Layer.MasksToBounds = true;
        vUpdatedEntry.TextAlignment = UITextAlignment.Left;
       }
    
      }
     }
    }

    In the above iOS implementation of the effect, we are adding the code to create the control manually in ‘ConfigureControl’ method, where we are adding the ShowPass and HidePass icons to the entry control, changing them on the basis of user touch action and attaching it on effect invocation, which will be fired when the effect is added to the control.

    Just like Android, make sure that you have ShowPass and HidePass images in your Resources folder of the iOS project, like the following image:

    Using the Effect

    In order to use the effect, we will just have to add the effect to the entry control in XAML, like in the following code:

    <Entry IsPassword="true" Placeholder="Password" Text="Password">
        <Entry.Effects>
            <ef:ShowHidePassEffect />
        </Entry.Effects>
    </Entry>

    And if you want to use it inside your C# code, you can do that with the following code:

    var vPasswordEntry = new Entry() { IsPassword=true };
    vPasswordEntry.Effects.Add(new FontEffect());

    This is how a sample application whose code is published on GitHub looks on executing.

    iOS Simulator

    Android Simulator

    This is one simple tip to implement a Show/Hide password feature in your Xamarin.Forms mobile apps. I will try to come up with more such tips in the future; let me know if I have missed anything or if you have any suggestions/concerns/queries.

    Topics:
    mobile ,mobile app development ,xamarin.forms ,xamarin

    Published at DZone with permission of

    Opinions expressed by DZone contributors are their own.

    {{ parent.title || parent.header.title}}

    {{ parent.tldr }}

    {{ parent.urlSource.name }}