Account for RTL on Android Tablet (#15417)

* Account for RTL on Android Tablet

* - additional RTL fixes

* - added comments

* Update build-osx.yml

Co-authored-by: Gerald Versluis <gerald.versluis@microsoft.com>
This commit is contained in:
Shane Neuville 2022-06-24 03:09:37 -05:00 коммит произвёл GitHub
Родитель 9f26f70d6a
Коммит b4f3eed8d3
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 109 добавлений и 23 удалений

Просмотреть файл

@ -274,15 +274,32 @@ namespace Xamarin.Forms.Platform.Android
{
//to keep some behavior we have on iPad where you can toggle and it won't do anything
bool isDefaultNoToggle = _parent.FlyoutLayoutBehavior == FlyoutLayoutBehavior.Default;
xPos = isFlyoutPage ? 0 : (_parent.IsPresented || isDefaultNoToggle ? DefaultWidthFlyout : 0);
if (_parent.FlowDirection == FlowDirection.RightToLeft)
{
double rightDp2 = Context.FromPixels(right);
xPos = isFlyoutPage ? rightDp2 - DefaultWidthFlyout : (_parent.IsPresented || isDefaultNoToggle ? 0 : rightDp2 - DefaultWidthFlyout);
}
else
{
xPos = isFlyoutPage ? 0 : (_parent.IsPresented || isDefaultNoToggle ? DefaultWidthFlyout : 0);
}
width = isFlyoutPage ? DefaultWidthFlyout : _parent.IsPresented || isDefaultNoToggle ? width - DefaultWidthFlyout : width;
}
else
{
//if we are showing the normal popover master doesn't have padding
supressPadding = isFlyoutPage;
if (_parent.FlowDirection == FlowDirection.RightToLeft && isFlyoutPage)
{
xPos = width - DefaultWidthFlyout;
}
//popover make the master smaller
width = isFlyoutPage && (Device.Info.CurrentOrientation.IsLandscape() || Device.Idiom == TargetIdiom.Tablet) ? DefaultWidthFlyout : width;
}
double padding = supressPadding ? 0 : Context.FromPixels(TopPadding);

Просмотреть файл

@ -308,31 +308,59 @@ namespace Xamarin.Forms.Platform.Android
base.OnLayout(changed, l, t, r, b);
//hack to make the split layout handle touches the full width
if (FlyoutPageController.ShouldShowSplitMode && _flyoutLayout != null)
_flyoutLayout.Right = r;
{
if (Element.FlowDirection == FlowDirection.RightToLeft)
_flyoutLayout.Left = l;
else
_flyoutLayout.Right = r;
}
}
async void DeviceInfoPropertyChanged(object sender, PropertyChangedEventArgs e)
async void UpdateFlyoutLayoutBehavior(bool requestLayout = false)
{
if (!FlyoutPageController.ShouldShowSplitMode && Presented)
{
FlyoutPageController.CanChangeIsPresented = true;
//hack : when the orientation changes and we try to close the Flyout on Android
//sometimes Android picks the width of the screen previous to the rotation
//this leaves a little of the flyout visible, the hack is to delay for 100ms closing the drawer
await Task.Delay(100);
//Renderer may have been disposed during the delay
if (_disposed)
{
return;
}
CloseDrawer(_flyoutLayout);
}
else if (FlyoutPageController.ShouldShowSplitMode)
{
OpenDrawer(_flyoutLayout, false);
}
UpdateSplitViewLayout();
if (requestLayout)
{
_flyoutLayout?.MaybeRequestLayout();
_detailLayout?.MaybeRequestLayout();
if (Device.Idiom == TargetIdiom.Tablet && _flyoutLayout != null)
{
// This is required to add/remove the drawer button
// This basically runs the same code that runs when
// a device changes between landscape/portrait
_detailLayout.GetFirstChildOfType<NavigationPageRenderer>()?.ResetToolbar();
}
}
}
void DeviceInfoPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (nameof(Device.Info.CurrentOrientation) == e.PropertyName)
{
if (!FlyoutPageController.ShouldShowSplitMode && Presented)
{
FlyoutPageController.CanChangeIsPresented = true;
//hack : when the orientation changes and we try to close the Flyout on Android
//sometimes Android picks the width of the screen previous to the rotation
//this leaves a little of the flyout visible, the hack is to delay for 100ms closing the drawer
await Task.Delay(100);
//Renderer may have been disposed during the delay
if (_disposed)
{
return;
}
CloseDrawer(_flyoutLayout);
}
UpdateSplitViewLayout();
UpdateFlyoutLayoutBehavior();
}
}
@ -373,7 +401,16 @@ namespace Xamarin.Forms.Platform.Android
else if (e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName)
UpdateBackgroundColor(Element);
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
{
UpdateFlowDirection();
// This will move the drawer layout button to the proper side of the toolbar
_detailLayout.GetFirstChildOfType<NavigationPageRenderer>()?.UpdateToolbar();
}
else if (e.Is(FlyoutPage.FlyoutLayoutBehaviorProperty))
{
UpdateFlyoutLayoutBehavior(true);
}
}
void FlyoutPageAppearing(object sender, EventArgs e)

Просмотреть файл

@ -736,7 +736,7 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
});
}
void ResetToolbar()
internal void ResetToolbar()
{
AToolbar oldToolbar = _toolbar;
@ -933,7 +933,7 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
ToolbarExtensions.UpdateMenuItemIcon(context, menuItem, toolBarItem, null);
}
void UpdateToolbar()
internal void UpdateToolbar()
{
if (_disposed)
return;
@ -982,6 +982,13 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
{
toggle.DrawerIndicatorEnabled = _flyoutPage.ShouldShowToolbarButton();
toggle.SyncState();
// When pivoting between split mode and flyout mode
// The DrawerArrowDrawable Progress will get out of sync and show a back button
// this forces it back to a hamburger
if (toggle.DrawerArrowDrawable != null)
toggle.DrawerArrowDrawable.Progress = 0;
}
}

Просмотреть файл

@ -23,5 +23,27 @@ namespace Xamarin.Forms.Platform.Android
}
}
}
public static T GetFirstChildOfType<T>(this AViewGroup viewGroup) where T : AView
{
for (var i = 0; i < viewGroup.ChildCount; i++)
{
AView child = viewGroup.GetChildAt(i);
if (child is T typedChild)
return typedChild;
if (child is AViewGroup vg)
{
var descendant = vg.GetFirstChildOfType<T>();
if (descendant != null)
{
return descendant;
}
}
}
return null;
}
}
}

Просмотреть файл

@ -61,6 +61,9 @@ steps:
inputs:
provProfileSecureFile: 'Xamarin Forms iOS Provisioning.mobileprovision'
- bash: rm -rf ~/.config/NuGet/NuGet.Config
displayName: 'Workaround to make build work'
- task: Bash@3
displayName: 'Build Control Gallery IPA'
inputs: