,
20 Mrz

Datentypen: Simple App mit Float, Integer und String (Android App Tutorial)

In diesem Tutorial geht es um drei wichtige Datentypen, die dir nicht nur in der Programmierung für Android begegnen werden: Float, Integer und String. Anhand einer einfachen App wirst du hier einen Crashkurs dazu bekommen. 🙂

Datentypen in Android: Float, Integer und String

 

Warum sind Datentypen wichtig?

Wenn du ein Programm schreiben willst, musst du früher oder später zwangsläufig Datentypen verwenden. Sei es eine Variable, die Bedingung für eine Schleife oder der Text eines Eingabefelds: All das benötigt Datentypen. Vielleicht hast du schon mit einem gearbeitet, konntest ihn aber noch nicht als „Datentyp“ benennen. Oder du kommst bei Float und Integer durcheinander. Deshalb hier ein „Kurzprofil“ der drei Datentypen aus diesem Tutorial:

  • Integer. Das, was man als Ganzzahl bezeichnet. Zum Beispiel „3“. Hier gibt es keine Kommata, keine Drittel und schon gar keine achthundertstel.
  • Float. Gleitkommazahlen, etwa „3,14“. Im englischen Sprachraum und deshalb in der Programmierung: „3.14“. (Float kann auch mit ganzen Zahlen umgehen. Wenn ausschließlich Ganzzahlen verwendet werden, ist vielleicht Integer die bessere Wahl.)
  • String. Textketten, Wörter, Buchstabenfolgen. Auch Zahlen können in Strings umgewandelt werden, zum Beispiel für Eingabefelder. (Mehr dazu unten…)

(Natürlich gibt es noch viel mehr über diese Datentypen zu erfahren, beispielsweise über ihre Wertebereiche oder mögliche Operatoren. Aber für unser Tutorial und den allerersten Einstieg benötigt ihr dieses Wissen noch nicht.)

 

 

Datentypen in Aktion: Spritverbrauchsrechner

Um dieses Grundlagentutorial mit einem Beispiel zu ergänzen, habe ich eine mehr oder weniger sinnvolle App gewählt. Sie ist recht einfach und zeigt dabei gut die Verwendung und die Grenzen von String, Integer und Float: Einen Spritverbrauchsrechner. Oder Benzinverbrauchsrechner. Oder Dieselverbrauchsrechner. Meinetwegen könnt ihr damit auch ausrechnen, wie viele Liter Wasser ihr trinken müsst, um 100 Kilometer Fahrradfahren durchzuhalten. 😉 Diese App verwendet die bereits angekündigten Datentypen auf folgende Weise:

  • String, um Text zu verarbeiten.
  • Float, um den Verbrauch zu berechnen.
  • Integer, um zu zeigen, wieso Float die bessere Wahl ist. 😉

Wie immer habe ich für das Projekt eine leere Activity ausgewählt, diesmal mit der Minimum-SDK „API 21“ (Android 5.0). Ihr könnt aber auch eine andere API auswählen. Wichtig ist allein, dass es mit eurem Test-Gerät oder Emulator kompatibel ist.

 

 

Die strings.xml

Wir verwenden für diese App eine Datei, die nur einen einzigen Zweck hat: Die Datei strings.xml (zu finden unter res/values) wird nur zum „Aufbewahren“ von Strings verwendet. Wenn ihr sie öffnet, ist zumindest der String „app_name“ bereits enthalten. Ich habe ein paar weitere Strings hinzugefügt, die in der App verwendet werden:

<resources>
 <string name="app_name">Spritrechner</string>
 <string name="anleitung">Gib die getankte Menge in Litern und die zurückgelegte Distanz in Kilometern ein und drücke dann auf \"berechnen\".</string>
 <string name="liter">Liter Sprit</string>
 <string name="kilometer">Gefahrene Kilometer</string>
 <string name="infinity">Bitte überprüfe noch einmal deine Eingaben.</string>
</resources>

Diese Strings können von überall her aufgerufen werden:

  • In der activity_main.xml (und anderen XML-Dateien) geschieht das über android:text=“@string/[stringname]“,
  • in der MainActivity.java (und anderen Java-Dateien) durch die Verwendung von R.string.[stringname] bzw getString(R.string.[stringname]).

Direkt im zweiten String („anleitung“) könnt ihr eine Besonderheit sehen: Der String enthält Backslashes und Anführungszeichen (\“). Es handelt sich bei diesen Backslashes um einen sogenannten escape character (eingedeutscht: Fluchtzeichen oder -symbol): Das auf den Backslash folgende Zeichen wird vom Compiler nicht als Teil des Codes behandelt sondern als Teil des Strings. Würde ich nicht \“ schreiben, wäre der String direkt nach dem ersten Anführungszeichen ‚zu Ende‘. (Ihr müsst euch in diesem Fall ein Anführungszeichen an den Anfang und eins ans Ende jedes Strings aus der Datei denken – siehe nächster Abschnitt.)

 

 

Die activity_main.xml

Das Design dieser App ist simpel: Bei mir ein vertikales lineares Layout, darin ein TextView und zwei horizontale Layouts mit jeweils einem EditText und einem TextView. Darauf folgen ein Button und ein weiteres TextView für das Ergebnis (zu Anfang leer). Für die Inhalte der TextViews verwende ich die oben gezeigten Strings aus der Datei res/values/strings.xml.

Spritrechner-App: Layout bzw. activity_main.xml

Spritrechner-App: Layout bzw. activity_main.xml

Wichtig ist, dass alle verwendeten Objekte eine eindeutige (und mehr oder weniger sinnvolle) Bezeichnung haben. Das erleichtert nicht nur die Verwendung sondern hilft auch, den Code später noch zu verstehen. 😉

Aus der activity_main.xml:

 <TextView
 android:text="@string/anleitung"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:id="@+id/tAnleitung"
 android:textAppearance="@android:style/TextAppearance.Material.Medium"
 android:paddingTop="2dp"
 android:paddingBottom="2dp" />

Das ist das oberste TextView. Dort soll der Inhalt des Strings „anleitung“ stehen. Also wird dem TextView mit android:text=“@string/anleitung“ der Text dieses Strings zugewiesen.

 

Darauf folgt das erste horizontale Layout (TextView und EditText für Liter-Angaben):

<LinearLayout
 android:orientation="horizontal"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:paddingBottom="2dp"
 android:paddingTop="2dp">

<TextView
 android:text="@string/liter"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:id="@+id/tLiter"
 android:layout_weight="3.25"
 android:textAppearance="@android:style/TextAppearance.Material.Medium" />

<EditText
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="0"
 android:ems="10"
 android:id="@+id/eLiter"
 android:layout_weight="1"
 android:inputType="numberDecimal"
 android:textAlignment="textEnd" />

</LinearLayout>

Dem TextView wird als Text der String „liter“ zugewiesen. Das EditText hat den Input Type  „numberDecimal“. Ruft man ein solches TextEdit auf, wird eine spezial auf die Eingabe von (Dezimal-)Zahlen abgestimmte Tastatur angezeigt. Buchstaben, Sonderzeichen oder negative Zahlen zu verwenden ist nicht möglich. Wir können faul sein und auf ein Filtern der Eingabe verzichten. Das macht die App bzw. Android für uns. 😉

Für Dezimalzahlen: Bei "numberDecimal" wird diese (oder eine ähnliche) Tastatur eingeblendet.

Für Dezimalzahlen: Bei „numberDecimal“ wird diese (oder eine ähnliche) Tastatur eingeblendet.

Das zweite horizontale Layout enthält ein TextView (tKilometer, mit String „kilometer“) und ein EditText (eKilometer, auch numberDecimal).

Den Abschluss bilden ein Button und ein TextView (tErgebnis), in dem das Ergebnis angezeigt werden soll:

<Button
 android:text="Berechnen"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:id="@+id/bBerechnen"
 style="@style/Widget.AppCompat.Button.Colored" />

<TextView
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:id="@+id/tErgebnis"
 android:textAppearance="@android:style/TextAppearance.Material.Medium"
 android:paddingBottom="2dp"
 android:paddingTop="2dp"/>

Was Höhen, Breiten und style/textAppearance angeht, könnt ihr euch frei austoben. Das gilt auch für die Padding-Werte. Wählt das, was euch gefällt. 🙂

 

 

Die MainActivity.java

Der maaaagische Moment ist da: sowohl für den Rechner, als auch für die Datentypen. Jetzt lassen wir die kreativen Aspekte hinter uns und widmen uns der knallharten Logik. 😉

Zunächst müssen wir einen OnClickListener für den Button erstellen. An das Ende der onCreate-Methode kommen folgende zwei Zeile:

Button bBerechnen = (Button) findViewById(R.id.bBerechnen);
bBerechnen.setOnClickListener(this);

Ihr könnt jetzt entweder Android Studio die Arbeit übernehmen lassen (indem ihr einen Rechtsklick auf das unterschlängelte „this“ macht und AS die Methode onClick implementieren lasst) oder ihr erstellt euch die Methode selbst.

Das hier ist jetzt der Inhalt meiner onClick-Methode, die ich mal in drei Abschnitte eingeteilt (und per // kommentiert) habe:

@Override
 public void onClick(View v) {

//1.: EditText für Kilometer, für  Liter und TextView für das Ergebnis
 EditText eKM = (EditText) findViewById(R.id.eKilometer);
 EditText eLi = (EditText) findViewById(R.id.eLiter);
 TextView tErgebnis = (TextView) findViewById(R.id.tErgebnis);

//2.: Variablen für die Inhalte der Textfelder: Zweimal Float
float liter = Float.valueOf(eLi.getText().toString());
float distanz = Float.valueOf(eKM.getText().toString());

//3.: Prüfen, ob die eingegebenen Zahlen beide größer als 0 sind
if (distanz>0 && liter>0) {
    //Wenn ja, dann...
    //... Verbrauch berechnen
    float verbrauch = liter * 100 / distanz;
    //... und Ergebnis-Text in TextView setzen
    tErgebnis.setText("Der Verbrauch beträgt " + String.valueOf(verbrauch) + " Liter pro 100 Kilometer.");
 } else {
    //Sonst den String Infinity ausgeben
    tErgebnis.setText(R.string.infinity);
 }
}

Im 1. Abschnitt werden die EditTexts und das TextView für das errechnete Ergebnis identifiziert. Alles bekommt (mehr oder weniger) sinnvolle Namen.

Aber was passiert im 2. Abschnitt, dem Variablen-Teil? Nehmen wir als Beispiel diese Zeile, der Einfachheit halber ein bisschen eingefärbt:

float liter = Float.valueOf(eLi.getText().toString());
  • eLi.getText(): Der Text in einem EditText/Textfeld ist kein Integer oder Float und auch kein String. Es handelt sich stattdessen um den Datentyp CharSequence, egal ob das Textfeldes „2“, „2.523“ oder „acht“ enthält. Der Datentyp wird nicht automatisch erkannt.
  • .toString(): Der Inhalt des Textfelds wird von CharSequence zu String konvertiert, damit wir damit arbeiten können.
  • Float.valueOf(…): Hier wird der Wert des Strings in einen Float umgewandelt. Wenn der String „0“ ist, entspricht der Wert 0 und der Float ist dementsprechend auch 0.
  • float liter: Die Variable liter ist vom Typ Float, also eine Gleitkommazahl. Dazu mehr im Abschnitt unten. 😉

Der eingegebene Text wird also in einen String konvertiert, der wiederum in einen Float umgewandelt wird. So können wir mit der Zahl – hier der Litermenge – rechnen. Bei der Angabe der Distanz wird es genauso gemacht.

Im 3. Abschnitt könnte die If-Else-Verzweigung theoretisch ausgelassen werden. Damit gibt man den Benutzern der App aber die Möglichkeit, durch 0 zu teilen. 😉 Heraus kommt dann ein Ergebnis wie dieses:

Links: Wer durch Null teilt, hat einen unendlich hohen Spritverbrauch. ;-) Rechts: Die Eingaben werden überprüft und bei Ungültigkeit gibt es eine entsprechende Anmerkung.

Links: Wer durch Null teilt, hat einen unendlich hohen Spritverbrauch. Rechts: Die Eingaben werden vor der Verarbeitung geprüft.

 

Der errechnete Verbrauch kann nicht einfach als Text des TextViews gesetzt werden. Denn: Ein TextView braucht als Text einen String, verbrauch ist aber Float.

tErgebnis.setText("Der Verbrauch beträgt " + String.valueOf(verbrauch) + " Liter pro 100 Kilometer.");

Also verwenden wir wieder valueOf(). Diesmal allerdings String.valueOf(), denn wir wollen den Wert eines Floats in einen String umwandeln. Hier wird gewissermaßen die Konvertierung von oben rückgängig gemacht.

Zusätzlich bekommt das TextView noch ein bisschen nettes Blahblah in String-Form zugewiesen. Dafür verwende ich in meinem Beispiel keinen String aus der strings.xml, sondern füge mittels Anführungszeichen den Text hinzu. Um diesen Blahblah-Text mit dem Verbrauch zu verbinden, wird das + als Operator verwendet. (Mehr zu Operatoren gibt es z.B. hier in der englischen Wikipedia.)

 

 

Warum Float und nicht Integer?

Es gibt bestimmt Fälle, in denen Integer besser ist als Float. Wenn es z.B. um Warenbestellungen geht (wer will schon 1,6 Hosen kaufen?) oder anderweitig mit ganzen Dingen oder Zahlen gerechnet wird, reicht Integer. Sobald aber irgendeine Art von Bruch oder Bruchstück verwendet wird (z.B. bei Preisangaben oder Division), ist der Datentyp Float die bessere Wahl.

Natürlich könnte man auch für eine Spritrechner-App Integer verwenden. Allerdings ist dann das Ergebnis nicht unbedingt zu gebrauchen.

Integer vs. Float: Berechnungen mit Ganzzahlen sind ungenau. Mit Gleitkommazahlen stimmt der Verbrauch.

Integer vs. Float: Berechnungen mit Ganzzahlen sind ungenau. Mit Gleitkommazahlen stimmt der Verbrauch.

Dieses Beispiel zeigt: Dass der Spritverbrauch irgendwo im Bereich um „5“ ist, stimmt (vom Rundungsfehler abgesehen). Aber wer seinen Verbrauch genauer ausrechnen möchte, kommt an Float nicht vorbei.

Die grundlegende Frage zur Verwendung von Float und Integer ist also immer: Wie wird was mit den Werten gemacht? 😉 Sobald ihr das wisst, könnt ihr euch sehr schnell für einen Datentyp entscheiden.

 



🙂 Klick hier für Bücher zum Thema Android-Programmierung!* 🙂