在圆形区域Xamarin Android中移动/动画TextView

时间:2019-02-22 08:02:34

标签: c# xamarin xamarin.android objectanimator

我有一个带有文本“ O”的TextView。 我想在一个圆形区域中移动/设置动画,并且不希望它超出该区域。 我可以使用下面的代码片段对其进行动画处理:

ObjectAnimator.OfFloat(txtTitle,"translationY",850).SetDuration(1000).Start();

translationY更改为850。我也可以为translationX做这件事,但它可以绕圈而行。翻译的值(在代码中是850)是随机的,我认为850是px而不是dp。这是我的第一个问题。我无法为dp值设置对象的动画。有没有办法修复它?

如果我能找到一种方法来移动带有dp值的对象,则可以用一点数学将其动画化为一个圆。 但是,如果没有办法,如何在圆形区域中对物体进行动画/移动?

1 个答案:

答案 0 :(得分:0)

它可以脱离“圆圈”的原因有两个:

首先,Android不包括翻译的空间限制。如果愿意,您可以在屏幕外翻译项目(通常这样做是为了使小部件在屏幕上消失的印象)。您可以剪辑到包含的布局或任何喜欢的形状,这样就不会在其外部绘制项目,但是它仍会在边缘消失,不会被包含在其中。

第二,无论绘制什么内容,Android(和iOS)中的所有可视元素实际上都是矩形。因此,即使您将小部件绑定到包含布局的边缘,它也仍然会退出绘制圆的边界,因为系统不知道那是什么。

所以。您需要自己进行计算,并确定圆的边界在哪里,并确保“平移X和Y”永远不会超出其范围。请参阅此https://www.mathopenref.com/coordbasiccircle.html,以获得有关如何执行此操作的参考。

然后您会发现增加了一个复杂的问题,即确定翻译后的视图与圆形边界相交的位置并相应地进行调整(请记住,翻译后的视图实际上是一个包含“绘制对象”的矩形)。如果您的“绘制对象”是一个精确的圆,这很容易(您可以通过其半径进行调整)。鉴于您正在使用圆,您可能希望将标准笛卡尔坐标系转换为极坐标系并使用弧度。

如果使用的是CV库,则它可能附带一种用于计算点或对象是否在一个区域内或两个区域相交的方法。您也可以在https://en.m.wikipedia.org/wiki/Point_in_polygon处找到一些提示。游戏库通常包含丰富的此类算法选择,可以精确地执行此类操作,因此您可能还需要检查其中的一些(那里有几个开源库)。

除非您确实需要绘制字符,否则如果您想要精确的翻译效果,我会避免使用它们,因为字体具有内置的填充,通常您无法使用。在您的情况下,请使用环形Drawable作为View或FrameLayout的背景,而不是TextView的背景。

如@ G.hakim所述,使用可绘制对象作为背景是创建圆的最简单方法。如果您想使事情更复杂,则必须创建自己的类并覆盖Draw或使用类似SkiaSharp library之类的东西(顺便说一句,太好了)。正如他所说,您可以使用以下标准转换轻松地在密度测量(dp和sp)和像素之间转换:

public static class PixelSizeConverter
{
    private static float _density = -1f;
    public static float Density
    {
        get
        {
            if (_density == -1)
                _density = Resources.System.DisplayMetrics.Density;
            return _density;
        }
    }

    private static float _scaledDensity = -1f;
    public static float ScaledDensity
    {
        get
        {
            if (_scaledDensity == -1)
                _scaledDensity = Resources.System.DisplayMetrics.ScaledDensity;
            return _scaledDensity;
        }
    }

    public static int DpToPx(float dp)
    {
        return (int) (dp * Density);
    }
    public static float PxToDp(float px)
    {
        return px / Density;
    }
    public static int SpToPx(float sp)
    {
        return (int) (sp * ScaledDensity);
    }

    public static float PxToSp(float px)
    {
        return px / ScaledDensity;
    }

}

祝你好运!