Dienstag, 24. Dezember 2013

Frohe Weihnachten

Ich wünsche allen meinen Lesern frohe Weihnachten, ein paar besinnliche Tage und einen guten Rutsch ins neue Jahr.
Hoffen wir, dass möglichst viele Menschen auf der Welt ein unbeschwertes Weihnachtsfest genießen können.

private void Form1_Paint(object sender, PaintEventArgs e)
{
    System.Drawing.Drawing2D.GraphicsPath GP = new System.Drawing.Drawing2D.GraphicsPath();
    GP.AddArc(50, 50, 40, 40, 180, 180);
    GP.AddArc(90, 50, 40, 40, 180, 180);
    GP.AddLine(130, 70, 90, 120);
    GP.AddLine(90, 120, 50, 70);
    e.Graphics.DrawPath(new Pen(new SolidBrush(Color.Red), 3), GP);
}

Freitag, 20. Dezember 2013

Dezimaltrennzeichen herausfinden

Oft kann es von Vorteil oder sogar notwendig sein, das Dezimaltrennzeichen des Systems bzw. des aktuellen Nutzers herauszufinden, um zum Beispiel Eingaben von Zahlen in das richtige Format zu bringen. In C# gelangen wir mit der Klasse CultureInfo an diese Information:

string DecimalSeparator = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;

Donnerstag, 19. Dezember 2013

Android: Dezimaltrennzeichen herausfinden

In vielen Anwendungen möchte man vielleicht Zahlen im korrekten Anzeigeformat der Nutzer darstellen oder Zahlen einlesen.
Da Visual Studio und Xamarin als Dezimaltrenner den Dezimalpunkt (".") verwenden, muss hierbei eventuell je nach verwendetem Trennzeichen des Benutzers eine manuelle Konvertierung der Zahl erfolgen.
Deswegen in diesem Post 2 Zeilen Code, mit denen sich das verwendete Dezimaltrennzeichen des Systems ermitteln lässt:

Java.Text.DecimalFormatSymbols FormatSymbols = new Java.Text.DecimalFormatSymbols();
char DecimalSeparator = FormatSymbols.DecimalSeparator;

Montag, 16. Dezember 2013

Android: Animationen verbinden

Nachdem ich im vorigen Post Gundlegendes zu Animationen in Android erklärt habe, möchte ich heute zeigen, wie man mit einem AnimatorSet mehrere Animationen verbindet und diese nacheinander oder miteinander abspielt.
Das Grundgerüst ist fast identisch zu dem aus dem vorigen Post, nur dieses Mal haben wir 2 TextViews, die nach Klick auf den Button animiert werden sollen:

using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;

using Android.Animation;

namespace AnimationsExample
{
     [Activity (Label = "AnimationsExample", MainLauncher = true)]
     public class MainActivity : Activity
     {
          protected override void OnCreate (Bundle bundle)
          {
               base.OnCreate (bundle);

               LinearLayout Layout = new LinearLayout (this);
               Layout.Orientation = Orientation.Vertical;

               TextView TxtView1 = new TextView (this);
               TxtView1.Text = "I'm flying";
               Layout.AddView (TxtView1);

               TextView TxtView2 = new TextView (this);
               TxtView2.Text = "I'm flying 2";
               Layout.AddView (TxtView2);

               Button Btn1 = new Button (this);
               Btn1.Text = "Animation";
               Layout.AddView (Btn1);

               Btn1.Click += (object sender, EventArgs e) => {
                    // Animation
               };

               SetContentView (Layout);
          }
     }
}

Nun erstellen wir zuerst, wie im vorigen Post beschrieben, 2 Animationen vom Typ ObjectAnimator, welche jeweils ein TextView nach rechts verschieben:

ObjectAnimator Animator1 = ObjectAnimator.OfInt(TxtView1, "Left", 0, 100);
Animator1.SetDuration(1000);
ObjectAnimator Animator2 = ObjectAnimator.OfInt(TxtView2, "Left", 0, 100);
Animator2.SetDuration(1000);

Um dem Titel gerecht zu werden kommt nun ein Objekt vom Typ AnimatorSet ins Spiel. Von diesem rufen wir zuerst die Methode Play() auf, welche eine Animation als Parameter erwartet. Das Besondere an einem AnimationSet ist nun, dass weitere Animationen aufgerufen werden können. Wir hängen diese entweder durch Aufruf der Methode With() oder Before() an, die Animationen werden dann entweder zusammen mit der ersten Animation oder danach abgespielt. Wie bei einzelnen Animationen auch muss am Schluss Start() aufgerufen werden. Folgender Code bewegt zuerst das obere TextView nach rechts, dann das untere:

ObjectAnimator Animator1 = ObjectAnimator.OfInt(TxtView1, "Left", 0, 100);
Animator1.SetDuration(1000);
ObjectAnimator Animator2 = ObjectAnimator.OfInt(TxtView2, "Left", 0, 100);
Animator2.SetDuration(1000);
AnimatorSet Combined = new AnimatorSet();
Combined.Play(Animator1).Before(Animator2);
Combined.Start();

Zu beachten ist hierbei, dass nur 2 zeitliche Ebenen zur Verfügung stehen, der Aufruf Play(A1).Before(A2).Before(A3) würde also die beiden Animationen A2 und A3 zeitgleich nach Animation A1 abspielen. Soll die Verschachtelung tiefer gehen, müssen mehrere AnimatorSets verwendet werden oder die Funktion PlaySequentially(). Diese erwartet eine Liste mit Elementen vom Typ Grundtyp Animator (ihr können also einzelne Animationen oder ganze AnimatorSets übergeben werden) und spielt diese dann nacheinander ab.
Möchte man viele Animationen ordnen, ist außerdem die Funktionen PlayTogether() nützlich, welche ebenfalls eine Liste von Animationen erwartet und diese gleichzeitig abspielt.

Samstag, 14. Dezember 2013

Android: Animationen einfügen

Im heutigen Post möchte ich beschreiben, wie man mit Animationen etwas mehr Leben in die eigenen Android Apps hauchen kann.
Bei der Android Programmierung gibt es hierfür im wensentlichen 3 Möglichkeiten, es gibt View Animations, Drawable Animations und Property Animations. In diesem Post möchte ich nur die letzte Klasse abdecken, welche zuletzte eingeführt wurde (in Android 3.0) und daher auch die meisten Möglichkeiten bietet und auch normalerweise genutzt wird.
Bei den Property Animations wiederrum gibt es 3 Subklassen: ValueAnimator, ObjectAnimator und AnimationSet. AnimationSet ist zuständig zum Verbinden mehrerer Animationen, dieser Klasse werde ich demnächst einen eigenen Post widmen.
Mit dem ValueAnimator lassen sich beliebige Eigenschaften über die Zeit verändern. In diesem Post möchte ich jedoch nur die Verwendung der Unterklasse ObjectAnimator beschreiben, welche speziell für das Animieren von Objekten erstellt wurde, was für die meisten Anwendungen ausreichten sollte.
Nun direkt zum Code. Im Beispiel erstellen wir ein LinearLayout, in welchem eine TextView und ein Button untereinander angeordnet werden, und die TextView per Animation nach Klick auf den Button nach rechts bewegt wird.
Zum Animieren brauchen wir den Namespace Android.Animation, welchen wir per using einbinden.
Dann erstellen wir den Animator von der Klasse ObjectAnimator aus und wählen hierbei, ob wir eine Integer oder Float Eigenschaft verändern müssen. Dieser Erzeugungsmethode übergeben wir dann den Namen des zu animierenden Objekts, den Namen der Zieleigenschaft als String und Start- und Endwert. Die folgenden Zeilen ändern die Eigenschaft Left des Objekts TxtView1 von 0 auf 100, verschieben das Objekt also nach rechts. In der zweiten Zeile legen wir die Dauer der Animation in Millisekunden fest, und in der dritten Zeile starten wir schließlich die Animation:

ObjectAnimator Animator = ObjectAnimator.OfInt(TxtView1, "Left", 0, 100);
Animator.SetDuration(1000);
Animator.Start();

Der komplette Code lautet:

using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;

using Android.Animation;

namespace AnimationsExample
{
     [Activity (Label = "AnimationsExample", MainLauncher = true)]
     public class MainActivity : Activity
     {
          protected override void OnCreate (Bundle bundle)
          {
               base.OnCreate (bundle);

               LinearLayout Layout = new LinearLayout (this);
               Layout.Orientation = Orientation.Vertical;

               TextView TxtView1 = new TextView (this);
               TxtView1.Text = "I'm flying";
               Layout.AddView (TxtView1);

               Button Btn1 = new Button (this);
               Btn1.Text = "Animation";
               Layout.AddView (Btn1);

               Btn1.Click += (object sender, EventArgs e) => {
                    ObjectAnimator Animator = ObjectAnimator.OfInt(TxtView1, "Left", 0, 100);
                    Animator.SetDuration(1000);
                    Animator.Start();
               };

               SetContentView (Layout);
          }
     }
}