Skip to content

Commit

Permalink
为消除dp与px的转换损耗,使用单独的DpToPx与PxToDp方法统一转换,其中在Density基础上增加了100的缩放比例,弥补转换损…
Browse files Browse the repository at this point in the history
…耗,因此在Constraintlayout内部测量过程中使用的是放大100倍的像素值,因此不能公开设置像素值
  • Loading branch information
xtuzy committed Apr 26, 2024
1 parent 9c97527 commit c98b8b0
Show file tree
Hide file tree
Showing 16 changed files with 252 additions and 256 deletions.
10 changes: 5 additions & 5 deletions SharpConstraintLayout.Maui.Example/Pages/MainPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ void FlowPerformanceTest(ConstraintLayout rootpage)
{
var page = new ConstraintLayout(new Log());
rootpage.AddElement(page);
page.ConstrainWidth = ConstraintSet.MatchParent;
page.ConstrainHeight = ConstraintSet.MatchParent;
page.ConstrainWidth = SizeBehavier.MatchParent;
page.ConstrainHeight = SizeBehavier.MatchParent;
using(var rootSet = new FluentConstraintSet())
{
rootSet.Clone(rootpage);
Expand Down Expand Up @@ -318,7 +318,7 @@ void NestedConstraintLayoutTest(ConstraintLayout page)
{
DebugName = "Second",
Background = new SolidColorBrush(Colors.Yellow),
ConstrainWidth = ConstraintSet.WrapContent,
ConstrainWidth = SizeBehavier.WrapContent,
};
rightLayout.AddElement(rightChildView);
rightChildView.Add(FirstButton);
Expand Down Expand Up @@ -666,7 +666,7 @@ private void ConstraintLayoutInListViewTest(ListView listView)
var dataTemplate = new DataTemplate(() =>
{
var viewCell = new ViewCell();
var layout = new ConstraintLayout(new Log()) { ConstrainWidth = ConstraintSet.MatchParent, ConstrainHeight = ConstraintSet.WrapContent, BackgroundColor = Color.FromRgb(66, 66, 66) };
var layout = new ConstraintLayout(new Log()) { ConstrainWidth = SizeBehavier.MatchParent, ConstrainHeight = SizeBehavier.WrapContent, BackgroundColor = Color.FromRgb(66, 66, 66) };
var title = new Label() { TextColor = Colors.White, FontSize = 30, FontAttributes = FontAttributes.Bold };
title.SetBinding(Label.TextProperty, nameof(Models.MicrosoftNews.Title));
var image = new Image();
Expand Down Expand Up @@ -754,7 +754,7 @@ void buildUIForConstraintLayout()
scrollViewForConstraintLayout.Orientation = ScrollOrientation.Vertical;
(Button FirstButton, Button SecondButton, ContentView ThirdCanvas, Label FouthTextBlock, Entry FifthTextBox, Editor SixthRichTextBlock) = CreateControls();
FirstButton.Text = "ConstraintLayout InScrollView";
var constraintlayout = new ConstraintLayout(new Log()) { ConstrainWidth = ConstraintSet.MatchParent, ConstrainHeight = ConstraintSet.WrapContent, BackgroundColor = Colors.Pink };
var constraintlayout = new ConstraintLayout(new Log()) { ConstrainWidth = SizeBehavier.MatchParent, ConstrainHeight = SizeBehavier.WrapContent, BackgroundColor = Colors.Pink };
scrollViewForConstraintLayout.Content = constraintlayout;
constraintlayout.AddElement(FirstButton, SecondButton, ThirdCanvas);
using (var set = new FluentConstraintSet())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,22 +85,22 @@ public void RemoveAllElements()
/// <param name="availableSize"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public (bool isInfinityAvailabelWidth, bool isInfinityAvailabelHeight) IsInfinitable(ConstraintLayout layout, int constrainWidth, int constrainHeight, Size availableSize)
public (bool isInfinityAvailabelWidth, bool isInfinityAvailabelHeight) IsInfinitable(ConstraintLayout layout, int constrainWidth, int constrainHeight, SizeI availableSize)
{
throw new NotImplementedException();
}
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
//base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
MeasureLayout(new Size(SharpConstraintLayout.Maui.Widget.MeasureSpec.GetSize(widthMeasureSpec), SharpConstraintLayout.Maui.Widget.MeasureSpec.GetSize(heightMeasureSpec)), widthMeasureSpec, heightMeasureSpec);
var size = MeasureLayout(new SizeI(SharpConstraintLayout.Maui.Widget.MeasureSpec.GetSize(widthMeasureSpec), SharpConstraintLayout.Maui.Widget.MeasureSpec.GetSize(heightMeasureSpec)), widthMeasureSpec, heightMeasureSpec);
SetMeasuredDimension(size.Width, size.Height);
}

protected override void OnLayout(bool changed, int l, int t, int r, int b)
{
ArrangeLayout();
}

void LayoutChild(UIElement element, int x, int y, int w, int h)
internal partial void LayoutChild(UIElement element, int x, int y, int w, int h)
{
element.Layout(x, y, x + w, y + h);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,20 +59,21 @@ public void RemoveAllElements()

protected override Size MeasureOverride(Size availableSize)
{
/*
* Analysis available size
*/
(int horizontalSpec, int verticalSpec) = MakeSpec(this, availableSize);
//availableSize use dp as unit, convert it to px
var availableSizeI = new SizeI(UIElementExtension.DpToPx(availableSize.Width, Density), UIElementExtension.DpToPx(availableSize.Height, Density));

var size = MeasureLayout(availableSize, horizontalSpec, verticalSpec);
return new Size(size.Width, size.Height);
(int horizontalSpec, int verticalSpec) = MakeSpec(this, availableSizeI);

var finalSize = MeasureLayout(availableSizeI, horizontalSpec, verticalSpec);
//return dp
return new Size(UIElementExtension.PxToDp(finalSize.Width, Density), UIElementExtension.PxToDp(finalSize.Height, Density));
}

/// <summary>
/// 判断是否可以无限大小
/// </summary>
/// <returns></returns>
public (bool isInfinityAvailabelWidth, bool isInfinityAvailabelHeight) IsInfinitable(ConstraintLayout layout, int constrainWidth, int constrainHeight, Size availableSize)
public (bool isInfinityAvailabelWidth, bool isInfinityAvailabelHeight) IsInfinitable(ConstraintLayout layout, int constrainWidth, int constrainHeight, SizeI availableSize)
{
bool isInfinityAvailabelWidth = false;
bool isInfinityAvailabelHeight = false;
Expand All @@ -98,9 +99,10 @@ protected override Size ArrangeOverride(Size finalSize)
if (finalSize.Width != mLastMeasureWidth || finalSize.Height != mLastMeasureHeight)
{
// We haven't received our desired size. We need to refresh the rows.
(int horizontalSpec, int verticalSpec) = MakeSpec(this, finalSize);
var size = MeasureLayout(finalSize, horizontalSpec, verticalSpec);
finalSize = new Size(size.Width, size.Height);
var finalSizeI = new SizeI(UIElementExtension.DpToPx(finalSize.Width, Density), UIElementExtension.DpToPx(finalSize.Height, Density));//maui's dp to px
(int horizontalSpec, int verticalSpec) = MakeSpec(this, finalSizeI);
var size = MeasureLayout(finalSizeI, horizontalSpec, verticalSpec);
finalSize = new Size(UIElementExtension.PxToDp(size.Width, Density), UIElementExtension.PxToDp(size.Height, Density));
}

ArrangeLayout();
Expand All @@ -109,9 +111,9 @@ protected override Size ArrangeOverride(Size finalSize)
return finalSize;
}

void LayoutChild(UIElement element, int x, int y, int w, int h)
internal partial void LayoutChild(UIElement element, int x, int y, int w, int h)
{
element.Arrange(new Rect(x, y, w, h));
element.Arrange(new Rect(UIElementExtension.PxToDp(x, Density), UIElementExtension.PxToDp(y, Density), UIElementExtension.PxToDp(w, Density), UIElementExtension.PxToDp(h, Density)));
}

#endregion
Expand Down
17 changes: 11 additions & 6 deletions SharpConstraintLayout.Maui.Native/Widget/ConstraintLayout.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ public override Size IntrinsicContentSize
}
}

/// <summary>
/// return dp as unit.
/// </summary>
/// <returns></returns>
public CGSize MeasureSubviews()
{
Size availableSize;
Expand Down Expand Up @@ -149,16 +153,17 @@ public CGSize MeasureSubviews()

}

(int horizontalSpec, int verticalSpec) = MakeSpec(this, availableSize);
var size = MeasureLayout(availableSize, horizontalSpec, verticalSpec);
return new CGSize(size.Width, size.Height);
var availableSizeI = new SizeI(UIElementExtension.DpToPx(availableSize.Width, Density), UIElementExtension.DpToPx(availableSize.Height, Density));
(int horizontalSpec, int verticalSpec) = MakeSpec(this, availableSizeI);
availableSizeI = MeasureLayout(availableSizeI, horizontalSpec, verticalSpec);
return new CGSize(UIElementExtension.PxToDp(availableSizeI.Width, Density), UIElementExtension.PxToDp(availableSizeI.Height, Density));
}

/// <summary>
/// 判断是否可以无限大小,作为UIScrollView的Child时可能.
/// </summary>
/// <returns></returns>
public (bool isInfinityAvailabelWidth, bool isInfinityAvailabelHeight) IsInfinitable(ConstraintLayout layout, int constrainWidth, int constrainHeight, Size availableSize)
public (bool isInfinityAvailabelWidth, bool isInfinityAvailabelHeight) IsInfinitable(ConstraintLayout layout, int constrainWidth, int constrainHeight, SizeI availableSize)
{
bool isInfinityAvailabelWidth = false;
bool isInfinityAvailabelHeight = false;
Expand Down Expand Up @@ -210,7 +215,7 @@ public override void LayoutSubviews()
if (DEBUGCONSTRAINTLAYOUTPROCESS) Debug.WriteLine($"{this.GetType().Name} {nameof(LayoutSubviews)} Finish: Frame={this.Frame} Bounds={this.Bounds} Widget={this.MLayoutWidget.ToString()}");
}

private void LayoutChild(UIElement element, int x, int y, int w, int h)
internal partial void LayoutChild(UIElement element, int x, int y, int w, int h)
{
//参考https://github.com/youngsoft/MyLinearLayout/blob/master/MyLayout/Lib/MyBaseLayout.m,设置Bounds
//element.Bounds = new CoreGraphics.CGRect(element.Bounds.X, element.Bounds.Y, w, h);
Expand All @@ -219,7 +224,7 @@ private void LayoutChild(UIElement element, int x, int y, int w, int h)
//探讨设置Frame还是Bounds
//Frame和Bounds在旋转View时是不同的大小,我们使用IntrinsicContentSize得到控件大小,那么IntrinsicContentSize是谁的大小呢?
//参考https://zhangbuhuai.com/post/auto-layout-part-1.html,这里好像暗示使用Frame去布局
element.Frame = new CoreGraphics.CGRect(x, y, w, h);
element.Frame = new CoreGraphics.CGRect(UIElementExtension.PxToDp(x, Density), UIElementExtension.PxToDp(y, Density), UIElementExtension.PxToDp(w, Density), UIElementExtension.PxToDp(h, Density));
}

#endregion
Expand Down
99 changes: 37 additions & 62 deletions SharpConstraintLayout.Maui/Helper/Widget/Flow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,14 @@

namespace SharpConstraintLayout.Maui.Helper.Widget
{
using androidx.constraintlayout.core.widgets.analyzer;
using Microsoft.Extensions.Logging;
using Microsoft.Maui.Devices;
using SharpConstraintLayout.Maui.Helper.Widget.Interface;
using SharpConstraintLayout.Maui.Widget;
using System.Collections.Generic;
using AndroidMeasureSpec = SharpConstraintLayout.Maui.Widget.MeasureSpec;
using ConstraintWidget = androidx.constraintlayout.core.widgets.ConstraintWidget;
using HelperWidget = androidx.constraintlayout.core.widgets.HelperWidget;
using AndroidMeasureSpec = SharpConstraintLayout.Maui.Widget.MeasureSpec;
using SharpConstraintLayout.Maui.Helper.Widget.Interface;
using Microsoft.Extensions.Logging;
using Microsoft.Maui.Devices;

/// <summary>
/// Flow VirtualLayout. <b>Added in 2.0</b>
Expand Down Expand Up @@ -190,7 +189,7 @@ public override void onMeasure(androidx.constraintlayout.core.widgets.VirtualLay
//this.WidthRequest = layout.Width;
//this.HeightRequest = layout.Height;给WidthRequest赋值造成测量循环

MeasuredSize = new Size(layout.MeasuredWidth, layout.MeasuredHeight);
MeasuredSize = new SizeI(layout.MeasuredWidth, layout.MeasuredHeight);
#elif __ANDROID__ && !__MAUI__
SetMeasuredDimension(layout.MeasuredWidth, layout.MeasuredHeight);//Android中这个的作用应该是设置flow的大小
#elif __IOS__ && !__MAUI__
Expand Down Expand Up @@ -243,12 +242,12 @@ public virtual void SetOrientation(int orientation)
/// doc see <see cref="SetPadding"/>
/// </summary>
/// <param name="value">unit is dp</param>
public virtual void SetPaddingDp(int value) => SetPadding((int)(value * DeviceDisplay.MainDisplayInfo.Density + 0.5));
public virtual void SetPaddingDp(int value) => SetPadding(UIElementExtension.DpToPx(value, DeviceDisplay.MainDisplayInfo.Density));
/// <summary>
/// Set padding around the content
/// </summary>
/// <param name="padding">unit is pixel</param>
public virtual void SetPadding(int value)
void SetPadding(int value)
{
mFlow.Padding = value;
this.RequestReLayout();
Expand All @@ -258,59 +257,35 @@ public virtual void SetPadding(int value)
/// doc see <see cref="SetPaddingLeft"/>
/// </summary>
/// <param name="value">unit is dp</param>
public virtual void SetPaddingLeftDp(int value) => SetPaddingLeft((int)(value * DeviceDisplay.MainDisplayInfo.Density + 0.5));
public virtual void SetPaddingDp(Edge edge, float value) => SetPadding(edge, UIElementExtension.DpToPx(value, DeviceDisplay.MainDisplayInfo.Density));
/// <summary>
/// Set padding left around the content
/// </summary>
/// <param name="paddingLeft"></param>
public virtual void SetPaddingLeft(int value)
{
mFlow.PaddingLeft = value;
this.RequestReLayout();
}

/// <summary>
/// doc see <see cref="SetPaddingTop"/>
/// </summary>
/// <param name="value">unit is dp</param>
public virtual void SetPaddingTopDp(int value) => SetPaddingTop((int)(value * DeviceDisplay.MainDisplayInfo.Density + 0.5));
/// <summary>
/// Set padding top around the content
/// </summary>
/// <param name="paddingTop"></param>
public virtual void SetPaddingTop(int value)
{
mFlow.PaddingTop = value;
this.RequestReLayout();
}

/// <summary>
/// doc see <see cref="SetPaddingRight"/>
/// </summary>
/// <param name="value">unit is dp</param>
public virtual void SetPaddingRightDp(int value) => SetPaddingRight((int)(value * DeviceDisplay.MainDisplayInfo.Density + 0.5));
/// <summary>
/// Set padding right around the content
/// </summary>
/// <param name="paddingRight"></param>
public virtual void SetPaddingRight(int value)
/// <param name="value">pixel as unit</param>
void SetPadding(Edge edge, int value)
{
mFlow.PaddingRight = value;
this.RequestReLayout();
}
switch (edge)
{
case Edge.Left:
mFlow.PaddingLeft = value;
break;
case Edge.Right:
mFlow.PaddingRight = value;
break;
case Edge.Top:
mFlow.PaddingTop = value;
break;
case Edge.Bottom:
mFlow.PaddingBottom = value;
break;
case Edge.Start:
mFlow.PaddingStart = value;
break;
case Edge.End:
mFlow.PaddingEnd = value;
break;
}

/// <summary>
/// doc see <see cref="SetPaddingBottom"/>
/// </summary>
/// <param name="value">unit is dp</param>
public virtual void SetPaddingBottomDp(int value) => SetPaddingBottom((int)(value * DeviceDisplay.MainDisplayInfo.Density + 0.5));
/// <summary>
/// Set padding bottom around the content
/// </summary>
/// <param name="paddingBottom"></param>
public virtual void SetPaddingBottom(int value)
{
mFlow.PaddingBottom = value;
this.RequestReLayout();
}

Expand All @@ -336,7 +311,7 @@ public virtual void SetLastVerticalStyle(int style)
/// doc see <see cref="SetLastHorizontalBias"/>
/// </summary>
/// <param name="value">unit is dp</param>
public virtual void SetLastHorizontalBiasDp(int value) => SetLastHorizontalBias((int)(value * DeviceDisplay.MainDisplayInfo.Density + 0.5));
public virtual void SetLastHorizontalBiasDp(int value) => SetLastHorizontalBias(UIElementExtension.DpToPx(value, DeviceDisplay.MainDisplayInfo.Density));
/// <summary>
/// Set the bias of the last Horizontal column.
/// </summary>
Expand All @@ -351,7 +326,7 @@ public virtual void SetLastHorizontalBias(float value)
/// doc see <see cref="SetLastVerticalBias"/>
/// </summary>
/// <param name="value">unit is dp</param>
public virtual void SetLastVerticalBiasDp(int value) => SetLastVerticalBias((int)(value * DeviceDisplay.MainDisplayInfo.Density + 0.5));
public virtual void SetLastVerticalBiasDp(int value) => SetLastVerticalBias(UIElementExtension.DpToPx(value, DeviceDisplay.MainDisplayInfo.Density));
/// <summary>
/// Set the bias of the last vertical row.
/// </summary>
Expand Down Expand Up @@ -439,7 +414,7 @@ public virtual void SetFirstVerticalStyle(int value)
/// doc see <see cref="SetFirstHorizontalBias"/>
/// </summary>
/// <param name="value">unit is dp</param>
public virtual void SetFirstHorizontalBiasDp(int value) => SetFirstHorizontalBias((int)(value * DeviceDisplay.MainDisplayInfo.Density + 0.5));
public virtual void SetFirstHorizontalBiasDp(int value) => SetFirstHorizontalBias(UIElementExtension.DpToPx(value, DeviceDisplay.MainDisplayInfo.Density));
/// <summary>
/// Similar to <see cref="SetHorizontalBias"/>, but only applied to the first chain.
/// </summary>
Expand All @@ -454,7 +429,7 @@ public virtual void SetFirstHorizontalBias(float value)
/// doc see <see cref="SetFirstVerticalBias"/>
/// </summary>
/// <param name="value">unit is dp</param>
public virtual void SetFirstVerticalBiasDp(int value) => SetFirstVerticalBias((int)(value * DeviceDisplay.MainDisplayInfo.Density + 0.5));
public virtual void SetFirstVerticalBiasDp(int value) => SetFirstVerticalBias(UIElementExtension.DpToPx(value, DeviceDisplay.MainDisplayInfo.Density));
/// <summary>
/// Similar to <see cref="SetVerticalBias"/>, but only applied to the first chain.
/// </summary>
Expand Down Expand Up @@ -495,7 +470,7 @@ public virtual void SetVerticalAlign(int value)
/// doc see <see cref="SetHorizontalGap"/>
/// </summary>
/// <param name="value">unit is dp</param>
public virtual void SetHorizontalGapDp(int value) => SetHorizontalGap((int)(value * DeviceDisplay.MainDisplayInfo.Density + 0.5));
public virtual void SetHorizontalGapDp(int value) => SetHorizontalGap(UIElementExtension.DpToPx(value, DeviceDisplay.MainDisplayInfo.Density));
/// <summary>
/// Set up the horizontal gap between elements
/// </summary>
Expand All @@ -510,7 +485,7 @@ public virtual void SetHorizontalGap(int value)
/// doc see <see cref="SetVerticalGap"/>
/// </summary>
/// <param name="value">unit is dp</param>
public virtual void SetVerticalGapDp(int value) => SetVerticalGap((int)(value * DeviceDisplay.MainDisplayInfo.Density + 0.5));
public virtual void SetVerticalGapDp(int value) => SetVerticalGap(UIElementExtension.DpToPx(value, DeviceDisplay.MainDisplayInfo.Density));
/// <summary>
/// Set up the vertical gap between elements
/// </summary>
Expand Down
Loading

0 comments on commit c98b8b0

Please sign in to comment.