我们目前正在使用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解决方案吗?
答案 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);
}
});
}
}
它的作用:
您只需要注意上面代码中的OscillatingSurface
类;其他一切只是例如。
资源: