Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

[Android] Entry Clear button invisible if BackgroundColor is a dark color #12391

Merged
merged 6 commits into from
Jul 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;

#if UITEST
using Xamarin.Forms.Core.UITests;
using Xamarin.UITest;
using NUnit.Framework;
#endif

namespace Xamarin.Forms.Controls.Issues
{
#if UITEST
[Category(UITestCategories.ManualReview)]
#endif
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 12380, "[Bug] Android: Entry Clear button becomes invisible when changing Entry.BackgroundColor to dark color",
PlatformAffected.Android | PlatformAffected.iOS)]
public class Issue12380 : TestContentPage
{
public Issue12380()
{
}

protected override void Init()
{
Title = "Issue 12380";

var layout = new StackLayout();

var instructions = new Label
{
Padding = 12,
BackgroundColor = Color.Black,
TextColor = Color.White,
Text = "The ClearButton must be visible in all cases."
};

var defaultLabel = new Label
{
Text = "Default ClearButton"
};

var defaultEntry = new Entry
{
ClearButtonVisibility = ClearButtonVisibility.WhileEditing
};

var whiteClearButtonLabel = new Label
{
Text = "White ClearButton"
};

var whiteClearButtonEntry = new Entry
{
BackgroundColor = Color.Black,
ClearButtonVisibility = ClearButtonVisibility.WhileEditing,
TextColor = Color.White
};

var yellowClearButtonLabel = new Label
{
Text = "Yellow ClearButton"
};

var yellowClearButtonEntry = new Entry
{
BackgroundColor = Color.Black,
ClearButtonVisibility = ClearButtonVisibility.WhileEditing,
TextColor = Color.Yellow
};

layout.Children.Add(instructions);
layout.Children.Add(defaultLabel);
layout.Children.Add(defaultEntry);
layout.Children.Add(whiteClearButtonLabel);
layout.Children.Add(whiteClearButtonEntry);
layout.Children.Add(yellowClearButtonLabel);
layout.Children.Add(yellowClearButtonEntry);

Content = layout;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1655,6 +1655,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Issue11081.xaml.cs">
<DependentUpon>Issue11081.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Issue12380.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue12372.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue12374.xaml.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue12222.cs" />
Expand Down
9 changes: 9 additions & 0 deletions Xamarin.Forms.Platform.Android/Renderers/EntryRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.ComponentModel;
using Android.Content;
using Android.Graphics;
using Android.Graphics.Drawables;
using Android.Text;
using Android.Text.Method;
Expand Down Expand Up @@ -629,6 +630,13 @@ void UpdateClearBtnOnTyping()
void UpdateClearBtn(bool showClearButton)
{
Drawable d = showClearButton && (Element.Text?.Length > 0) ? GetCloseButtonDrawable() : null;

if (!Element.TextColor.IsDefault)
d?.SetColorFilter(Element.TextColor.ToAndroid(), FilterMode.SrcIn);
else
d?.ClearColorFilter();


if ((Element as IVisualElementController).EffectiveFlowDirection.IsRightToLeft())
{
EditText.SetCompoundDrawablesWithIntrinsicBounds(d, null, null, null);
Expand All @@ -637,6 +645,7 @@ void UpdateClearBtn(bool showClearButton)
{
EditText.SetCompoundDrawablesWithIntrinsicBounds(null, null, d, null);
}

_clearBtn = d;
}

Expand Down
62 changes: 60 additions & 2 deletions Xamarin.Forms.Platform.iOS/Renderers/EntryRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ public abstract class EntryRendererBase<TControl> : ViewRenderer<Entry, TControl
static readonly int baseHeight = 30;
static CGSize initialSize = CGSize.Empty;

UIImage _defaultClearImage;

public EntryRendererBase()
{
}
Expand Down Expand Up @@ -551,7 +553,63 @@ void UpdateIsReadOnly()

void UpdateClearButtonVisibility()
{
Control.ClearButtonMode = Element.ClearButtonVisibility == ClearButtonVisibility.WhileEditing ? UITextFieldViewMode.WhileEditing : UITextFieldViewMode.Never;
if (Element.ClearButtonVisibility == ClearButtonVisibility.WhileEditing)
{
Control.ClearButtonMode = UITextFieldViewMode.WhileEditing;
UpdateClearButtonColor();
}
else
Control.ClearButtonMode = UITextFieldViewMode.Never;
}

void UpdateClearButtonColor()
{
if (Control.ValueForKey(new NSString("clearButton")) is UIButton clearButton)
{
clearButton.TintColor = Element.TextColor.ToUIColor();

if(_defaultClearImage == null)
_defaultClearImage = clearButton.ImageForState(UIControlState.Highlighted);

if(Element.TextColor == Color.Default)
{
clearButton.SetImage(_defaultClearImage, UIControlState.Normal);
clearButton.SetImage(_defaultClearImage, UIControlState.Highlighted);
}
else
{
var tintedClearImage = GetClearButtonTintImage(_defaultClearImage, Element.TextColor.ToUIColor());

clearButton.SetImage(tintedClearImage, UIControlState.Normal);
clearButton.SetImage(tintedClearImage, UIControlState.Highlighted);
}
}
}

UIImage GetClearButtonTintImage(UIImage image, UIColor color)
{
var size = image.Size;

UIGraphics.BeginImageContextWithOptions(size, false, UIScreen.MainScreen.Scale);

if (UIGraphics.GetCurrentContext() == null)
return null;

var context = UIGraphics.GetCurrentContext();

image.Draw(CGPoint.Empty, CGBlendMode.Normal, 1.0f);
context?.SetFillColor(color.CGColor);
context?.SetBlendMode(CGBlendMode.SourceIn);
context?.SetAlpha(1.0f);

var rect = new CGRect(CGPoint.Empty.X, CGPoint.Empty.Y, image.Size.Width, image.Size.Height);
context?.FillRect(rect);

var tintedImage = UIGraphics.GetImageFromCurrentImageContext();

UIGraphics.EndImageContext();

return tintedImage;
}
}
}
}