寻找相当于UIElement.RenderTransform来可视化Android中的偏差水平

时间:2014-11-26 13:21:31

标签: android animation graphics xamarin

我们目前正在使用Xamarin构建一个应用程序,我们希望可视化与中性值的偏差程度。当前状态将每80到150毫秒更新一次。

基本上我们正在寻找类似的东西:

----'''''----(偏向正面)

---- ----- ----(无偏差)

---- ___ ----(偏离负面)

外侧的线条将保持在同一位置,而中间的线条会上下移动以显示当前的偏差。

对于WP来说,就像在一行中绘制3个细长矩形并通过Rectangle.RenderTransform将Y轴上的值转换为中间矩形一样简单。

在Android中,我们使用LevelListDrawable将几个png绑定到某个值范围,并从代码中设置当前级别: 这是LevelList.xml:

<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android" >
  <item
      android:drawable="@drawable/down"
      android:minLevel="0"
      android:maxLevel="33" />
  <item
      android:drawable="@drawable/neutral"
      android:minLevel="34"
      android:maxLevel="66" />
  <item
      android:drawable="@drawable/top"
      android:minLevel="67"
      android:maxLevel="100" />
</level-list>

down,neutral和top指的是显示当前状态的.png。 (将有大约20个不同的州)

LevelList.xml设置为ImageView的ImageDrawable,用于显示当前状态:

_graphicsView = FindViewById<ImageView>(Resource.Id.GraphicsView);
var drawable = Resources.GetDrawable(Resource.Drawable.LevelList);
_graphicsView.SetImageDrawable(drawable);

这是MainActivity中的更新方法:

public void UpdateDeviation(int deviation)
{
    _graphicsView.SetImageLevel(deviation);
}

我们当前的方法正在发挥作用,但我们不满意为每个州存储大量的png。关于更新速度和APK大小,你能想到更好的Android解决方案吗?

1 个答案:

答案 0 :(得分:0)

你可以通过实现自己的SurfaceView并根据不同的状态渲染路径来改善这一点。

我很无聊所以我写了一个例子:

<强>代码:

public enum LineState
{
    Up, Middle, Down,
}

public class OscillatingSurface : SurfaceView
{
    public LineState _state = LineState.Middle;
    private readonly Paint _paint;

    public OscillatingSurface (Context context)
        : base(context) 
    {
        _paint = new Paint(PaintFlags.AntiAlias);
        _paint.SetStyle (Paint.Style.Stroke);
        _paint.Color = Color.White;
        _paint.StrokeWidth = 10.0f;
    }

    public void SetState(LineState state)
    {
        this._state = state;

        float factor = 0.5f;
        if (_state == LineState.Up) {
            factor = 0.6f;
        } else if (state == LineState.Down) {
            factor = 0.4f;
        }

        float width = (float)this.Width;
        float height = (float)this.Height;

        Path path = new Path();

        path.MoveTo (0.0f, height * 0.5f); // Far left point.
        path.LineTo (width * 0.25f, height * 0.5f); // Middle left point.
        path.LineTo (width * 0.25f, height * factor); // Left Oscilation point
        path.LineTo (width * 0.75f, height * factor); // Right oscilation point
        path.LineTo (width * 0.75f, height * 0.5f); // Middle right point.
        path.LineTo (width, height * 0.5f); // Far right point.

        var canvas = this.Holder.LockCanvas (); // Acquire surface.

        canvas.DrawColor (Color.Black); // Clear surface.
        canvas.DrawPath (path, _paint); // Render the path.

        Holder.UnlockCanvasAndPost (canvas); // Release and render!
    }
}

[Activity (Label = "Oscillating Surface", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
    OscillatingSurface surface;
    Oscillator oscillator;

    protected override void OnCreate (Bundle bundle)
    {
        base.OnCreate (bundle);
        surface = new OscillatingSurface (this);
        oscillator = new Oscillator (this, surface, 1000);
        SetContentView (surface);
    }

    protected override void OnResume ()
    {
        oscillator.Start ();
        base.OnResume ();
    }
}

public class Oscillator
{
    int _frequency;
    OscillatingSurface _surface;
    Activity _owner;

    public Oscillator(Activity owner, OscillatingSurface surface, int frequency)
    {
        _surface = surface;
        _frequency = frequency;
        _owner = owner;
    }

    public void Start()
    {
        System.Threading.Tasks.Task.Run (() => {
            while (true) {
                LineState next = (LineState)((((int)_surface._state) + 1) % 3);
                _owner.RunOnUiThread( () => {
                    _surface.SetState(next);
                });

                Thread.Sleep(_frequency);
            }
        });
    }
}

它的作用:

enter image description here enter image description here enter image description here

您只需要注意上面代码中的OscillatingSurface类;其他一切只是例如。

资源: