зеркало из https://github.com/DeGsoft/maui-linux.git
Implement HorizontalTextAlignment in SearchBarHandlers (#508)
* Implement HorizontalTextAlignment in SearchBarHandlers * Clean up, add comments, verify things work with and without RTL support on Android Co-authored-by: E.Z. Hart <hartez@gmail.com>
This commit is contained in:
Родитель
667eb0391b
Коммит
4e01228c45
|
@ -4,6 +4,7 @@ using AGravityFlags = Android.Views.GravityFlags;
|
|||
|
||||
namespace Microsoft.Maui.Controls.Compatibility.Platform.Android
|
||||
{
|
||||
[PortHandler]
|
||||
internal static class TextAlignmentExtensions
|
||||
{
|
||||
internal static void UpdateHorizontalAlignment(this EditText view, TextAlignment alignment, bool hasRtlSupport, AGravityFlags orMask = AGravityFlags.NoGravity)
|
||||
|
|
|
@ -172,6 +172,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Android
|
|||
ClearFocus(Control);
|
||||
}
|
||||
|
||||
[PortHandler]
|
||||
void UpdateHorizontalTextAlignment()
|
||||
{
|
||||
_editText = _editText ?? Control.GetChildrenOfType<EditText>().FirstOrDefault();
|
||||
|
|
|
@ -236,6 +236,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.iOS
|
|||
_textField.AttributedPlaceholder = _textField.AttributedPlaceholder.AddCharacterSpacing(Element.Placeholder, Element.CharacterSpacing);
|
||||
}
|
||||
|
||||
[PortHandler]
|
||||
void UpdateHorizontalTextAlignment()
|
||||
{
|
||||
_textField = _textField ?? Control.FindDescendantView<UITextField>();
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/// <summary>
|
||||
/// Represents a View used to initiating a search.
|
||||
/// </summary>
|
||||
public interface ISearchBar : IView, IPlaceholder
|
||||
public interface ISearchBar : IView, IPlaceholder, ITextAlignment
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a string containing the query text in the SearchBar.
|
||||
|
|
|
@ -1,12 +1,21 @@
|
|||
using AndroidX.AppCompat.Widget;
|
||||
using System.Linq;
|
||||
using Android.Widget;
|
||||
using SearchView = AndroidX.AppCompat.Widget.SearchView;
|
||||
|
||||
namespace Microsoft.Maui.Handlers
|
||||
{
|
||||
public partial class SearchBarHandler : AbstractViewHandler<ISearchBar, SearchView>
|
||||
{
|
||||
EditText? _editText;
|
||||
public EditText? QueryEditor => _editText;
|
||||
|
||||
protected override SearchView CreateNativeView()
|
||||
{
|
||||
return new SearchView(Context);
|
||||
var searchView = new SearchView(Context);
|
||||
|
||||
_editText = searchView.GetChildrenOfType<EditText>().First();
|
||||
|
||||
return searchView;
|
||||
}
|
||||
|
||||
public static void MapText(SearchBarHandler handler, ISearchBar searchBar)
|
||||
|
@ -18,5 +27,10 @@ namespace Microsoft.Maui.Handlers
|
|||
{
|
||||
handler.TypedNativeView?.UpdatePlaceholder(searchBar);
|
||||
}
|
||||
|
||||
public static void MapHorizontalTextAlignment(SearchBarHandler handler, ISearchBar searchBar)
|
||||
{
|
||||
handler.QueryEditor?.UpdateHorizontalTextAlignment(searchBar);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,5 +8,6 @@ namespace Microsoft.Maui.Handlers
|
|||
|
||||
public static void MapText(IViewHandler handler, ISearchBar searchBar) { }
|
||||
public static void MapPlaceholder(IViewHandler handler, ISearchBar searchBar) { }
|
||||
public static void MapHorizontalTextAlignment(IViewHandler handler, ISearchBar searchBar) { }
|
||||
}
|
||||
}
|
|
@ -5,7 +5,8 @@
|
|||
public static PropertyMapper<ISearchBar, SearchBarHandler> SearchBarMapper = new PropertyMapper<ISearchBar, SearchBarHandler>(ViewHandler.ViewMapper)
|
||||
{
|
||||
[nameof(ISearchBar.Text)] = MapText,
|
||||
[nameof(ISearchBar.Placeholder)] = MapPlaceholder
|
||||
[nameof(ISearchBar.Placeholder)] = MapPlaceholder,
|
||||
[nameof(ISearchBar.HorizontalTextAlignment)] = MapHorizontalTextAlignment
|
||||
};
|
||||
|
||||
public SearchBarHandler() : base(SearchBarMapper)
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
using System;
|
||||
using UIKit;
|
||||
|
||||
namespace Microsoft.Maui.Handlers
|
||||
{
|
||||
public partial class SearchBarHandler : AbstractViewHandler<ISearchBar, UISearchBar>
|
||||
{
|
||||
protected override UISearchBar CreateNativeView() => new UISearchBar();
|
||||
UITextField? _textField;
|
||||
|
||||
protected override UISearchBar CreateNativeView()
|
||||
{
|
||||
var searchBar = new UISearchBar();
|
||||
|
||||
_textField = searchBar.FindDescendantView<UITextField>();
|
||||
|
||||
return searchBar;
|
||||
}
|
||||
|
||||
public static void MapText(SearchBarHandler handler, ISearchBar searchBar)
|
||||
{
|
||||
|
@ -16,5 +24,10 @@ namespace Microsoft.Maui.Handlers
|
|||
{
|
||||
handler.TypedNativeView?.UpdatePlaceholder(searchBar);
|
||||
}
|
||||
|
||||
public static void MapHorizontalTextAlignment(SearchBarHandler handler, ISearchBar searchBar)
|
||||
{
|
||||
handler.TypedNativeView?.UpdateHorizontalTextAlignment(searchBar, handler._textField);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
using AndroidX.AppCompat.Widget;
|
||||
using SearchView = AndroidX.AppCompat.Widget.SearchView;
|
||||
|
||||
namespace Microsoft.Maui
|
||||
{
|
||||
|
|
|
@ -5,7 +5,7 @@ using Android.Widget;
|
|||
|
||||
namespace Microsoft.Maui
|
||||
{
|
||||
public static class LabelExtensions
|
||||
public static class TextViewExtensions
|
||||
{
|
||||
public static void UpdateText(this TextView textView, ILabel label)
|
||||
{
|
||||
|
@ -40,9 +40,20 @@ namespace Microsoft.Maui
|
|||
textView.SetTextSize(ComplexUnitType.Sp, sp);
|
||||
}
|
||||
|
||||
public static void UpdateHorizontalTextAlignment(this TextView textView, ILabel label)
|
||||
public static void UpdateHorizontalTextAlignment(this TextView textView, ITextAlignment text)
|
||||
{
|
||||
textView.Gravity = label.HorizontalTextAlignment.ToHorizontalGravityFlags();
|
||||
if (textView.Context!.HasRtlSupport())
|
||||
{
|
||||
// We want to use TextAlignment where possible because it doesn't conflict with the
|
||||
// overall gravity of the underlying control
|
||||
textView.TextAlignment = text.HorizontalTextAlignment.ToTextAlignment();
|
||||
}
|
||||
else
|
||||
{
|
||||
// But if RTL support is not available for some reason, we have to resort
|
||||
// to gravity, because Android will simply ignore text alignment
|
||||
textView.Gravity = text.HorizontalTextAlignment.ToHorizontalGravityFlags();
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdateLineBreakMode(this TextView textView, ILabel label)
|
|
@ -0,0 +1,28 @@
|
|||
using System.Collections.Generic;
|
||||
using AView = Android.Views.View;
|
||||
using AViewGroup = Android.Views.ViewGroup;
|
||||
|
||||
namespace Microsoft.Maui
|
||||
{
|
||||
public static class ViewGroupExtensions
|
||||
{
|
||||
public static IEnumerable<T> GetChildrenOfType<T>(this AViewGroup self) where T : AView
|
||||
{
|
||||
for (var i = 0; i < self.ChildCount; i++)
|
||||
{
|
||||
AView? child = self.GetChildAt(i);
|
||||
|
||||
if (child is T typedChild)
|
||||
yield return typedChild;
|
||||
|
||||
if (child is AViewGroup)
|
||||
{
|
||||
IEnumerable<T>? myChildren = (child as AViewGroup)?.GetChildrenOfType<T>();
|
||||
if (myChildren != null)
|
||||
foreach (T nextChild in myChildren)
|
||||
yield return nextChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,5 +13,23 @@ namespace Microsoft.Maui
|
|||
{
|
||||
uiSearchBar.Placeholder = searchBar.Placeholder;
|
||||
}
|
||||
|
||||
public static void UpdateHorizontalTextAlignment(this UISearchBar uiSearchBar, ISearchBar searchBar)
|
||||
{
|
||||
UpdateHorizontalTextAlignment(uiSearchBar, searchBar, null);
|
||||
}
|
||||
|
||||
public static void UpdateHorizontalTextAlignment(this UISearchBar uiSearchBar, ISearchBar searchBar, UITextField? textField)
|
||||
{
|
||||
textField ??= uiSearchBar.FindDescendantView<UITextField>();
|
||||
|
||||
if (textField == null)
|
||||
return;
|
||||
|
||||
// We don't have a FlowDirection yet, so there's nothing to pass in here.
|
||||
// TODO: Update this when FlowDirection is available
|
||||
// (or update the extension to take an ILabel instead of an alignment and work it out from there)
|
||||
textField.TextAlignment = searchBar.HorizontalTextAlignment.ToNative(true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,41 @@
|
|||
using Microsoft.Maui.Handlers;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Android.Widget;
|
||||
using Microsoft.Maui.DeviceTests.Stubs;
|
||||
using Microsoft.Maui.Handlers;
|
||||
using Xunit;
|
||||
using SearchView = AndroidX.AppCompat.Widget.SearchView;
|
||||
|
||||
namespace Microsoft.Maui.DeviceTests
|
||||
{
|
||||
public partial class SearchBarHandlerTests
|
||||
{
|
||||
[Fact(DisplayName = "Horizontal TextAlignment Initializes Correctly")]
|
||||
public async Task HorizontalTextAlignmentInitializesCorrectly()
|
||||
{
|
||||
var xplatHorizontalTextAlignment = TextAlignment.End;
|
||||
|
||||
var searchBarStub = new SearchBarStub()
|
||||
{
|
||||
Text = "Test",
|
||||
HorizontalTextAlignment = xplatHorizontalTextAlignment
|
||||
};
|
||||
|
||||
Android.Views.TextAlignment expectedValue = Android.Views.TextAlignment.ViewEnd;
|
||||
|
||||
var values = await GetValueAsync(searchBarStub, (handler) =>
|
||||
{
|
||||
return new
|
||||
{
|
||||
ViewValue = searchBarStub.HorizontalTextAlignment,
|
||||
NativeViewValue = GetNativeTextAlignment(handler)
|
||||
};
|
||||
});
|
||||
|
||||
Assert.Equal(xplatHorizontalTextAlignment, values.ViewValue);
|
||||
values.NativeViewValue.AssertHasFlag(expectedValue);
|
||||
}
|
||||
|
||||
SearchView GetNativeSearchBar(SearchBarHandler searchBarHandler) =>
|
||||
(SearchView)searchBarHandler.View;
|
||||
|
||||
|
@ -13,5 +44,16 @@ namespace Microsoft.Maui.DeviceTests
|
|||
|
||||
string GetNativePlaceholder(SearchBarHandler searchBarHandler) =>
|
||||
GetNativeSearchBar(searchBarHandler).QueryHint;
|
||||
|
||||
Android.Views.TextAlignment GetNativeTextAlignment(SearchBarHandler searchBarHandler)
|
||||
{
|
||||
var searchView = GetNativeSearchBar(searchBarHandler);
|
||||
var editText = searchView.GetChildrenOfType<EditText>().FirstOrDefault();
|
||||
|
||||
if (editText == null)
|
||||
return Android.Views.TextAlignment.Inherit;
|
||||
|
||||
return editText.TextAlignment;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +1,57 @@
|
|||
using Microsoft.Maui.Handlers;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Maui.DeviceTests.Stubs;
|
||||
using Microsoft.Maui.Handlers;
|
||||
using UIKit;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.Maui.DeviceTests
|
||||
{
|
||||
public partial class SearchBarHandlerTests
|
||||
{
|
||||
UISearchBar GetNativeEntry(SearchBarHandler searchBarHandler) =>
|
||||
[Fact(DisplayName = "Horizontal TextAlignment Updates Correctly")]
|
||||
public async Task HorizontalTextAlignmentInitializesCorrectly()
|
||||
{
|
||||
var xplatHorizontalTextAlignment = TextAlignment.End;
|
||||
|
||||
var searchBarStub = new SearchBarStub()
|
||||
{
|
||||
Text = "Test",
|
||||
HorizontalTextAlignment = xplatHorizontalTextAlignment
|
||||
};
|
||||
|
||||
UITextAlignment expectedValue = UITextAlignment.Right;
|
||||
|
||||
var values = await GetValueAsync(searchBarStub, (handler) =>
|
||||
{
|
||||
return new
|
||||
{
|
||||
ViewValue = searchBarStub.HorizontalTextAlignment,
|
||||
NativeViewValue = GetNativeTextAlignment(handler)
|
||||
};
|
||||
});
|
||||
|
||||
Assert.Equal(xplatHorizontalTextAlignment, values.ViewValue);
|
||||
values.NativeViewValue.AssertHasFlag(expectedValue);
|
||||
}
|
||||
|
||||
UISearchBar GetNativeSearchBar(SearchBarHandler searchBarHandler) =>
|
||||
(UISearchBar)searchBarHandler.View;
|
||||
|
||||
string GetNativeText(SearchBarHandler searchBarHandler) =>
|
||||
GetNativeEntry(searchBarHandler).Text;
|
||||
GetNativeSearchBar(searchBarHandler).Text;
|
||||
|
||||
string GetNativePlaceholder(SearchBarHandler searchBarHandler) =>
|
||||
GetNativeEntry(searchBarHandler).Placeholder;
|
||||
GetNativeSearchBar(searchBarHandler).Placeholder;
|
||||
|
||||
UITextAlignment GetNativeTextAlignment(SearchBarHandler searchBarHandler)
|
||||
{
|
||||
var uiSearchBar = GetNativeSearchBar(searchBarHandler);
|
||||
var textField = uiSearchBar.FindDescendantView<UITextField>();
|
||||
|
||||
if (textField == null)
|
||||
return UITextAlignment.Left;
|
||||
|
||||
return textField.TextAlignment;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,5 +7,7 @@
|
|||
public string Text { get => _text; set => SetProperty(ref _text, value); }
|
||||
|
||||
public string Placeholder { get; set; }
|
||||
|
||||
public TextAlignment HorizontalTextAlignment { get; set; }
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче