2014-11-26 3 views
2

В настоящее время мы создаем приложение с Xamarin, в котором мы хотим визуализировать уровень отклонения от нейтрального значения. Текущее состояние будет обновляться каждые 80-150 миллисекунд.Ищете эквивалент UIElement.RenderTransform для визуализации уровня отклонения в Android

В основном мы ищем что-то вроде этого:

----''''' ---- (отклонение к положительным)

---- ----- - нет --- (нет отклонения)

---- ---- ___ (отклонение к минусу)

линия на наружных собирается оставаться в том же положении, в то время как линия в середине двигается вверх и вниз, чтобы показать текущее отклонение.

Для WP это так же просто, как рисование 3 тонких прямоугольников в строке и перевод значений по оси Y в средний прямоугольник через Rectangle.RenderTransform.

В 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> 

вниз, нейтральной и сверху обратитесь к а. png, показывающее текущее состояние. (Там будут около 20 различных состояний)

LevelList.xml устанавливается как ImageDrawable для ImageView, который используется для отображения текущего состояния:

_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-х для каждого государства. Можете ли вы придумать лучшее решение для Android в отношении скорости обновления и размера APK?

ответ

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 hereenter image description hereenter image description here

Вы только действительно нужно оплачивать n к классу OscillatingSurface в вышеуказанном коде; все остальное - это только пример.

Ресурсы:

+0

Очень хорошее решение. Большое спасибо за обширный ответ! –

Смежные вопросы