Я создал свой собственный RibbonView, который выглядит следующим образом в ListViews
На первый взгляд он выглядит хорошо на всех платформах, но на Android он выглядит не очень хорошо, когда я прокручиваю назад к элементам в ListView, например, прокручиваю вниз, а затем обратно вверх.
Как единственный метод, который я вызываю для поворотаOnSizeAllocated
, это может быть оттуда или от настройки TranslationX
/ TranslationY
.
Мой код для RibbonView показан ниже
using System;
using System.Collections.Generic;
using Xamarin.Forms;
namespace App1
{
public class RibbonView : ContentView
{
public Point RotatedLowerLeftCorner { get; private set; }
public Point RotatedLowerRightCorner { get; private set; }
public Point RotatedUpperLeftCorner { get; private set; }
public Point RotatedUpperRightCorner { get; private set; }
protected override void OnSizeAllocated(double width, double height)
{
base.OnSizeAllocated(width, height);
var upperLeft = new Point(Content.Margin.Left + Padding.Left, Content.Margin.Top + Padding.Top);
var upperRight = upperLeft;
upperRight.X += width - Content.Margin.HorizontalThickness - Padding.HorizontalThickness;
var lowerLeft = upperLeft;
lowerLeft.Y += height - Content.Margin.VerticalThickness - Padding.VerticalThickness;
var lowerRight = upperRight;
lowerRight.Y = lowerLeft.Y;
var rotationPoint = new Point()
{
X = (lowerRight.X - upperLeft.X) * AnchorX + upperLeft.X,
Y = (lowerRight.Y - upperLeft.Y) * AnchorY + upperLeft.Y
};
RotatedLowerLeftCorner = CalculateRotatedPoint(lowerLeft, rotationPoint);
RotatedLowerRightCorner = CalculateRotatedPoint(lowerRight, rotationPoint);
RotatedUpperLeftCorner = CalculateRotatedPoint(upperLeft, rotationPoint);
RotatedUpperRightCorner = CalculateRotatedPoint(upperRight, rotationPoint);
var translationX = Math.Min(Math.Min(RotatedUpperLeftCorner.X, RotatedUpperRightCorner.X), Math.Min(RotatedLowerLeftCorner.X, RotatedLowerRightCorner.X)) * (HorizontalOptions.Alignment == LayoutAlignment.End ? 1 : -1);
var translationY = Math.Min(Math.Min(RotatedUpperLeftCorner.Y, RotatedUpperRightCorner.Y), Math.Min(RotatedLowerLeftCorner.Y, RotatedLowerRightCorner.Y)) * (VerticalOptions.Alignment == LayoutAlignment.End ? 1 : -1);
Device.BeginInvokeOnMainThread(() =>
{
TranslationX = translationX;
TranslationY = translationY;
});
CalculateSize(rotationPoint, translationX, translationY);
}
private Point AddTranslationsToPoint(Point p, double translationX, double translationY)
{
return new Point
{
X = p.X + translationX,
Y = p.Y + translationY
};
}
private Point CalculateRotatedPoint(Point p, Point rotationPoint)
{
var rotation = GetRotationInRadians();
return new Point
{
X = Math.Cos(rotation) * (p.X - rotationPoint.X) - Math.Sin(rotation) * (p.Y - rotationPoint.Y) + rotationPoint.X,
Y = Math.Sin(rotation) * (p.X - rotationPoint.X) + Math.Cos(rotation) * (p.Y - rotationPoint.Y) + rotationPoint.Y
};
}
private void CalculateSize(Point rotationPoint, double translationX, double translationY)
{
var upperLeft = new Point(0, 0);
var lowerLeft = new Point(Width, 0);
var lowerRight = new Point(Width, Height);
var upperRight = new Point(0, Height);
var outerBox = new List<Point>
{
AddTranslationsToPoint(CalculateRotatedPoint(upperLeft, rotationPoint), X + translationX, Y + translationY),
AddTranslationsToPoint(CalculateRotatedPoint(lowerLeft, rotationPoint), X + translationX, Y + translationY),
AddTranslationsToPoint(CalculateRotatedPoint(lowerRight, rotationPoint), X + translationX, Y + translationY),
AddTranslationsToPoint(CalculateRotatedPoint(upperRight, rotationPoint), X + translationX, Y + translationY)
};
var parentBox = new List<Point>();
if (Parent is VisualElement parentVisualElement)
{
parentBox.Add(new Point(0, 0));
parentBox.Add(new Point(parentVisualElement.Width, 0));
parentBox.Add(new Point(parentVisualElement.Width, parentVisualElement.Height));
parentBox.Add(new Point(0, parentVisualElement.Height));
}
}
private double GetRotationInRadians()
{
var rotationInDeg = Rotation;
while (rotationInDeg < 0)
{
rotationInDeg += 360;
}
return rotationInDeg * Math.PI / 180;
}
}
}
Я также создал образецприложение, которое можно загрузить с по этой ссылке Dropbox .
Я надеюсь, что кто-то здесь может помочь мне