Tag Archives: Improved Button

XFHACKS-006 Password Entry with show/hide Text feature!

Ever wished if your Xamarin.Forms Password Entry control had the option to reveal, or show the Password text that the User types on demand, instead of the black dots? 😉  Even better, without any Custom Renderers or Platform Specific code? Welcome to another lightening short post of me hacking around Xamarin.Forms elements!

So in Xamarin.Forms to enable this feature usually you need to resort to creating Custom Renderers or some platform specific implementation, which is a tedious process and a complicated implementation. So I thought of making use of my own crazy imagination and hack my way around to get this to work right from Xamarin.Forms itself!

No custom renderers, no platform specific code and no third party libraries! Just by using pure out of the box Xamarin.Forms! 😉

Sneak Peak!

That’s what we gonna be build yol!

XFHACKS Recipe!

Let the recipe begin! So basically the idea here is to have two Entry elements which represents the Entry with IsPassword enabled and another Entry with IsPassword disabled, laid on top of each other inside a Grid layout. Also we’re going to switch the visibility of these two Entry controls on a Button click event which will also be laid on top of both the Entry elements, aligned to the right most corner of the whole Grid layout. Just to add some cheery to the icing, let’s have a Button with an Icon Image inside of it, which implementation I’ll be extracting from one of my previous XFHACKS articles, XFHACKS-005 Button with full control on Text and Icon! ! Give it a read if you’re curious! 😉

Since we’re maintaining two Entry elements, we need to make sure both of them have the same Text value at any point of the user’s interaction. So to make this happen we’re going use Element to Element binding in Xamarin.Forms, where as we are binding the Text field properties of both Entry controls to eachother. Thereby one Entry’s Text changes immediately reflects on the other one and so on.

Just to show some love for my architectural practices, I’m going to move the whole Button click event and the handling of the behavior logic of this control into a TriggerAction, aha! separation of concern or loosely coupled and no direct code behind dependency allowing for more re-usability! 😀

Code!

Behold the golden XAML code!

<Grid
   Grid.Row="1"
   Grid.Column="0"
   HeightRequest="45"
   HorizontalOptions="FillAndExpand"
   IsClippedToBounds="True">

   <!--  Entry Password  -->
   <Entry
      x:Name="EntryPassword"
      Grid.Row="0"
      Grid.Column="0"
      FontSize="Medium"
      IsPassword="True"
      IsVisible="True"
      Keyboard="Plain"
      Placeholder="Password"
      Text="{Binding Source={x:Reference EntryText}, Path=Text, Mode=TwoWay}" />

   <!--  Entry Text  -->
   <Entry
      x:Name="EntryText"
      Grid.Row="0"
      Grid.Column="0"
      FontSize="Medium"
      IsPassword="False"
      IsVisible="False"
      Keyboard="Plain"
      Placeholder="Password"
      Text="{Binding Source={x:Reference EntryPassword}, Path=Text, Mode=TwoWay}" />

   <!--  Button with Icon  -->
   <Grid
      Grid.Row="0"
      Grid.Column="0"
      Padding="0,0,3,0"
      HeightRequest="27"
      HorizontalOptions="End"
      IsClippedToBounds="True"
      VerticalOptions="Center"
      WidthRequest="35">

      <!--  Button Control  -->
      <Button x:Name="ShowPasswordButton" BackgroundColor="White">
         <Button.Margin>
            <OnPlatform x:TypeArguments="Thickness">
               <On Platform="Android" Value="-4,-6,-4,-6" />
               <On Platform="iOS" Value="0" />
            </OnPlatform>
         </Button.Margin>
         <Button.Triggers>
            <EventTrigger Event="Clicked">
               <triggers:ShowPasswordTriggerAction
                  EntryPasswordName="EntryPassword"
                  EntryTextName="EntryText"
                  IconImageName="ShowPasswordButtonIcon" />
            </EventTrigger>
         </Button.Triggers>
      </Button>

      <!--  Icon Image  -->
      <Image
         x:Name="ShowPasswordButtonIcon"
         HeightRequest="25"
         HorizontalOptions="Fill"
         InputTransparent="True"
         Source="{extensions:ImageResource XFHacks.Resources.showpasswordicon.png}"
         VerticalOptions="Fill"
         WidthRequest="25" />
   </Grid>

</Grid>

 

Here we go, explanation time! So the two Entry elements are laying on top of each other and bound to each other’s Text properties, while having one Entry as IsPassword=true and the other opposite. I have given names for the Elements because we need references of them to handle the behaviour inside our TriggerAction which I will show next.

Then the Button with the Icon Image Element is aligned to the very right corner of Parent layout, laying on top of both Entry elements. I have added some padding to it to avoid it conflicting with the border of the Entry in iOS and UWP, then for Android it shouldn’t really matter visually. There’s a HeightRequest=”27″ and WidthRequest=”35″ given to this Element group because I needed to have some horizontal space besides the Image icon visually. For the Image we’re using a EmbeddedResource type image, which makes things really easy for managing the Images.

Then for the Parent Grid Layout that holds all of these Elements together,is using IsClippedToBounds property to make sure everything holds inside the Bounds of the Grid as a single UI Element.

This is the most crucial part where inside the Button click event we’re invoking a TrigerAction called ShowPasswordTriggerAction which handles all the logic and behaviour of this custom control. And we’re passing in the names of the Elements we have assigned, into the Trigger so that we can look it up inside the TriggerAction, retrieve their runtime references and handle the behavior as we need. Pretty straightforward implementation there 😉

Next let’s look into the golden TriggerAction!

/// <summary>
/// The Trigger Action that will handle
/// the Show/Hide Passeword text
/// </summary>
public class ShowPasswordTriggerAction : TriggerAction<Button>
{
    public string IconImageName { get; set; }

    public string EntryPasswordName { get; set; }

    public string EntryTextName { get; set; }

    protected override void Invoke(Button sender)
    {
        // get the runtime references 
        // for our Elements from our custom control
        var imageIconView = ((Grid) sender.Parent)
                  .FindByName<Image>(IconImageName);
        var entryPasswordView = ((Grid) ((Grid) sender.Parent).Parent).FindByName<Entry>(EntryPasswordName);
        var entryTextView = ((Grid)((Grid)sender.Parent).Parent).FindByName<Entry>(EntryTextName);

        // Switch visibility of Password 
        // Entry field and Text Entry fields
        entryPasswordView.IsVisible =     
                       !entryPasswordView.IsVisible;
        entryTextView.IsVisible = 
                       !entryTextView.IsVisible;

        // update the Show/Hide button Icon states 
        if (entryPasswordView.IsVisible)
        {
            // Password is not Visible state
            imageIconView.Source = ImageSource.FromResource(
                "XFHacks.Resources.showpasswordicon.png",
                Assembly.GetExecutingAssembly());

            // Setting up Entry curser focus
            entryPasswordView.Focus();
            entryPasswordView.Text = entryTextView.Text;
        }
        else
        {
            // Password is Visible state
            imageIconView.Source = ImageSource.FromResource(
                "XFHacks.Resources.hidepasswordicon.png",
                Assembly.GetExecutingAssembly());

            // Setting up Entry curser focus
            entryTextView.Focus();
            entryTextView.Text = entryPasswordView.Text;
        }
    }
}

 

Here’s the most important bit where we’re handling the behaviour logic of our awesome Password Entry Control! At the moment of Invoking the Button click we’re doing a simple FindByName<T> look up for our required Elements, that are the EntryPassword field, EntryText field, and the IconImage.

First of all we’re setting the visibility of the two Entry Elements opposite for each other, as in if the User clicks on Show Password state, then the Entry with Text property will be displayed, and the user clicks on Hide Password state then the Entry with Password property (black dots) will be displayed.

Then based on the state, we’re updating the button icon’s Image source, as you can see we’re setting the showpasswordicon.png and hidepasswordicon.png respectively depending on the current state.

Finally we’re doing something extra to make sure whatever the visible the Entry element is still on Focus after the switching of the Password visibility state.

There we go, pretty straight forward yeah!

 Important: You could also move that whole piece of XAML to a separate XAML file, so that you could set it up as a reusable Control in your project! 😉

Fire it up!

Alright let’s see this in action!

 

There you have it running on Android, iOS and UWP like a charm! 😀

NO CUSTOM RENDERERS! NO NATIVE CODE! MORE AWESOME! xD

Grab it on Github!

https://github.com/UdaraAlwis/XFHacks

Well then, that’s it for now. More awesome stuff on the way!

Cheers! 😀 share the love!

Improvement suggestion: I was discussing this with one of my colleagues and he pointed out an awesome tweak for a much better improvement, that is to use the same implementation with trigger and all but with a single Entry element with the IsPassword true and false state on demand instead of using two Entry elements. This is a great idea yet so simple, which will drastically improve the rendering performance. So if you wanna give it a crack please go ahead! And here’s a shout out to an awesome developer Akshay Kulkarni – ak47akshaykulkarnimake sure to check out his Github repo! 😉

Advertisements

XFHACKS-005 Button with full control on Text and Icon!

Ever came across an instance where you wished if you had more control or customization over the Text and Icon properties of your Xamarin.Forms Button? even better even without any Custom Renderers or Platform Specific code? Welcome to another lightening short post of me hacking around Xamarin.Forms elements!

Uh oh, in Xamarin.Forms?!

The default Xamarin.Forms Button has it’s own limitations for customisation, specially in the Text and Icon, there’s not much control over those properties in terms of,

  • Alignment of Text and Icon
  • Positioning of Text and Icon 
  • Default upper case Text in Android
  • Icon Image Size and Aspect Property
  • Icon Source only limited for Local Images

Talking of the Icon Source, you can only use Platform Specific Local Images for it, you cannot use Embedded Resources for it.

So I thought of making use of my own crazy imagination and hack my way around to fix all those limitations!

No custom renderers, no platform specific code and no third party libraries! Just by using pure out of the box Xamarin.Forms! 😉

Usual approach…

Now as an out of the box solution for this we could avoid using Xamarin.Forms Button totally and switch to a Xamarin.Forms Label or Image control with a Tap gesture recognizer attached to it. But then it wouldn’t actually give that nice look and feel of a button does it, specially in Android that nice ripple effects and on iOS the fade out effect on the button click is something really nice to have on your UI.

So… wait for it….

XFHACKS Receipe!

Here’s my awesome solution, we’re still going to stick to Xamarin.Forms Button button, and we’ll be laying down a Label or an Image on top of our Button view inside a Grid layout. This is actually very common hack of mine if you had gone through previous XFHACKS articles of my blog.

Yep sounds super simple, yet solves all of the issues I just mentioned above. Basically we’re constructing our own Custom Button control right from Xamarin.Forms elements, properties and behaviours without any custom renderers or platform code.

So getting into more details, here’s how we’re going to solve the above talked issues. For Alignment of the Text and Icon in the button, we are going to use the HorizontalOption of both Image and Label element that we’re placing on top of the Button. Then the Position of those elements, we shall resort to the Margin property of each. Since we’re using the Image control itself the Source property issue is automatically solved. Then as an added advantage you could also have the control over the Aspect property of the Image Icon you want to display in your button.

Now on top of all that one might wonder when you place a Label or Image on top of a Button, wouldn’t it obstruct the Clickable touch area of the Button? That’s where InputTransparent comes into rescue, passing down the touch even down to the Button straight away!

To add some cherry on top of the icing, we’re going to use the IsClippedToBounds property to crop out any areas of the inner elements of the Grid being rendered outside the View bounds of the Grid itself, so everything comes together as a single Element on UI.

Now all these comes together solving the issues that I have pointed out at the beginning! 😉

Sneak Peak!

That’s what we gonna be build yol!

Code and Run!

Behold the golden XAML code!

<!--  Button with Text and Icon  -->
<Grid
    Grid.Row="1"
    Grid.Column="0"
    HeightRequest="40"
    HorizontalOptions="Fill"
    IsClippedToBounds="True"
    VerticalOptions="Center">

    <!--  Button Control  -->
    <Button BackgroundColor="#2196F3">
        <Button.Margin>
            <OnPlatform x:TypeArguments="Thickness">
                <On Platform="Android" Value="-4,-6,-4,-5" />
                <On Platform="iOS" Value="0" />
            </OnPlatform>
        </Button.Margin>
    </Button>

    <!--  Text Label  -->
    <Label
        Margin="10,0,0,0"
        FontAttributes="Bold"
        FontSize="Small"
        HorizontalOptions="Start"
        HorizontalTextAlignment="Center"
        InputTransparent="True"
        Text="go next"
        TextColor="White"
        VerticalOptions="Center"
        VerticalTextAlignment="Center" />

    <!--  Icon Image  -->
    <Image
        Margin="0,0,5,0"
        HeightRequest="30"
        HorizontalOptions="End"
        InputTransparent="True"
        Source="{extensions:ImageResource XFHacks.Resources.rightarrowicon.png}"
        VerticalOptions="Center"
        WidthRequest="30" />
</Grid>

 

There you have it as we discussed earlier, our empty Button and on top of that the Label and the Image elements inside a Grid. As you can see the Button has some Margin value added for Android run time of, “-4,-6,-4,-5” which is to get rid of the default empty space that’s rendered around the Button at Android run time. The button will be spread across the whole Grid in background with its default HorizontalOptions=”Fill” property.

The Grid’s IsClippedToBounds=”True” property value makes sure it will cut off any inner elements that will render themselves out of the bounds of Grid. You can set whatever the HeightRequest or WidthRequest as you wish if you want to customize this even further.

Now speaking of the Label and Image you can see how I’m using the advantage of HorizontalOptions to align the elements as whatever the way I wish along with the Margin property of them, adding space wherever I wish. In here we have pushed the Label to the beginning of the Button and the Icon to the End of the Button horizontally.

Next the  InputTransparent=”True” comes in solving the touch issue, which will pass the touch action down to the Button element when the user clicks on it, giving the exact effect of a Button. The use of Image element we can now set whatever the size we wish for our Icon inside the button and adjust its Aspect property and so on.

And let’s try something else as well! Lets have a Button which has its Text and Icons aligned to the Right most corner.

<!--  Button with Text and Icon  -->
<Grid
    Grid.Row="0"
    Grid.Column="1"
    HeightRequest="40"
    HorizontalOptions="Fill"
    IsClippedToBounds="True"
    VerticalOptions="Center">

    <!--  Button Control  -->
    <Button Grid.ColumnSpan="2" BackgroundColor="#2196F3">
        <Button.Margin>
            <OnPlatform x:TypeArguments="Thickness">
                <On Platform="Android" Value="-4,-6,-4,-5" />
                <On Platform="iOS" Value="0" />
            </OnPlatform>
        </Button.Margin>
    </Button>

    <!--  Text Label  -->
    <Label
        Grid.Column="0"
        Margin="0,0,5,0"
        FontAttributes="Bold"
        FontSize="Small"
        HorizontalOptions="End"
        HorizontalTextAlignment="End"
        InputTransparent="True"
        Text="favs"
        TextColor="White"
        VerticalOptions="Center"
        VerticalTextAlignment="Center" />

    <!--  Icon Image  -->
    <Image
        Grid.Column="1"
        Margin="0,0,10,0"
        HeightRequest="30"
        HorizontalOptions="End"
        InputTransparent="True"
        Source="{extensions:ImageResource XFHacks.Resources.staricon.png}"
        VerticalOptions="Center"
        WidthRequest="30" />

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>
</Grid>

 

Here’s another example where I have pushed the Image Icon to the End of the Button and the Label to be following it horizontally.

You can follow the same implementation and have our Button’s Text and Icon aligned t other Left most corner.

Now just like that you can customize all the aspects of a Button using this hack I just shared, just set up the Label and Icon with whatever the properties and customization as you wish on top of a Button. That’s it!

 Important: You could also move that whole piece of XAML to a separate XAML file, so that you could set it up as a reusable Control in your project! 😉

Fire it up!

Let me share some examples I’ve built using this awesomeness!

There you go our awesome Custom Button control running on Android, as you can see with all the preserved Button click effect! 😀

 

Since its completely out of the box Xamarin.Forms, you can run it across all the native platforms and expect the same results! 😉

Grab it on Github!

https://github.com/UdaraAlwis/XFHacks

Well then, that’s it for now. More awesome stuff on the way!

Cheers! 😀 share the love!