Kursbuch

Website: Moodle, virtuelles Arbeiten und eLearning - Herzlich willkommen!
Kurs: Plattformübergreifende Mobile App-Entwicklung mit React Native: Vom Konzept zur Bewegungstracker-App für iOS und Android
Buch: Kursbuch
Gedruckt von: Guest user
Datum: Montag, 16. Februar 2026, 16:27

1. LS 2.1 Ereignisverarbeitung

Was ist Ereignisverarbeitung?

Ereignisverarbeitung bezeichnet den Prozess, bei dem ein Programm auf Benutzereingaben oder systemseitige Änderungen reagiert. Ereignisse treten in interaktiven Anwendungen auf, wenn der Nutzer beispielsweise einen Button drückt, Text eingibt oder ein Gerät bewegt.

Wichtige Begriffe

  • Ereignis (Event): Eine Aktion oder ein Signal, das vom Nutzer oder dem System ausgelöst wird (z. B. ein Klick, eine Berührung oder eine Gerätebewegung).
  • Event-Handler: Eine Funktion, die ausgeführt wird, wenn ein bestimmtes Ereignis eintritt.
  • Event-Listener: Eine Methode, die einem Element mitteilt, dass es auf ein bestimmtes Ereignis reagieren soll.
  • State (Zustand): Eine Variable, die sich durch ein Ereignis ändern kann, um den aktuellen Status einer Anwendung zu speichern.

Wie funktioniert Ereignisverarbeitung?

  1. Ein Ereignis tritt auf (z. B. der Nutzer klickt auf einen Button).
  2. Ein Event-Listener registriert das Ereignis.
  3. Ein Event-Handler wird ausgeführt und reagiert darauf (z. B. zeigt eine Nachricht an).
  4. Falls notwendig, wird der State aktualisiert.

Ereignisverarbeitung in React Native

In React Native gibt es keine direkte Entsprechung zu addEventListener wie im Web. Stattdessen werden Ereignisse über Props (z. B. onPress) und Hooks (z. B. useEffect) gesteuert.

Häufig verwendete Ereignisse in React Native

Ereignis React Native Methode Beispiel
Button-Klick onPress <Button title="Klick" onPress={() => alert('Button wurde gedrückt!')} />
Texteingabe onChangeText <TextInput onChangeText={(text) => setText(text)} />
Bildschirmrotation Dimensions.addEventListener('change', callback) useEffect(() => { Dimensions.addEventListener(...) }, [])

Warum ist Ereignisverarbeitung wichtig?

  • Sie ermöglicht interaktive Benutzeroberflächen.
  • Programme werden dynamisch anpassbar und können auf Nutzeraktionen reagieren.
  • Mobile Apps nutzen sie, um mit Hardware-Sensoren zu interagieren.

Zusammenfassung

Ereignisverarbeitung ist eine Schlüsseltechnologie in modernen Apps und Webanwendungen. Sie ermöglicht interaktive Anwendungen, indem sie Benutzereingaben erkennt und darauf reagiert. Dabei spielen Event-Handler, Event-Listener und States eine zentrale Rolle.

1.1. Button-Klick-Ereignis

Button-Klick-Ereignis

In React Native werden Benutzerinteraktionen, z. B. das Tippen auf einen Button, mit Ereignissen (Events) verarbeitet.
Dazu nutzen wir die Eigenschaft onPress.

Beispielcode:

<Button title="Klick mich!" onPress={() => alert('Button geklickt!')} />

Erklärung:

  • onPress erkennt, wenn der Button gedrückt wird.
  • alert('Button geklickt!') zeigt eine Nachricht auf dem Bildschirm an.

Tipp: Alternativen zu alert()

  • console.log() – um Text in der Entwicklerkonsole auszugeben (z. B. zur Fehlersuche).
  • useState – um Text im Interface anzuzeigen (z. B. „Button wurde geklickt!“).
  • Modal – für aufklappende Dialoge mit mehr Gestaltungsmöglichkeiten.

1.2. Texteingabe-Ereignis (onChangeText)

Texteingabe-Ereignis (onChangeText)

Texteingaben in React Native werden mit dem Event-Listener onChangeText verarbeitet.

Beispielcode:

<TextInput placeholder="Name eingeben" onChangeText={(text) => setInputText(text)} />

Erklärung:

  • Die eingegebene Zeichenkette (text) wird sofort an die Funktion setInputText weitergegeben.
  • setInputText aktualisiert eine State-Variable (inputText), wodurch sich die Ausgabe im Interface ändert.

1.3. Bildschirmrotation erkennen

Bildschirmrotation erkennen

Um auf Änderungen der Bildschirmgröße zu reagieren, z. B. bei Drehung des Geräts, verwenden wir den Event-Listener Dimensions.addEventListener.

Beispielcode:

useEffect(() => { const subscription = Dimensions.addEventListener('change', ({ window }) => { setScreenWidth(window.width); }); return () => subscription?.remove(); // Cleanup }, []);

Erklärung:

  • Dimensions.addEventListener: Erkennt Veränderungen der Bildschirmgröße.
  • setScreenWidth: Aktualisiert den aktuellen Zustand der Bildschirmbreite.
  • Der useEffect-Hook führt diesen Code beim Starten der Komponente aus und sorgt auch dafür, dass der Listener beim Schließen wieder entfernt wird.

1.4. Hintergrundwissen JSX – Warum {}?

Hintergrundwissen JSX – Warum {}?

In React Native nutzen wir geschweifte Klammern {}, um JavaScript innerhalb des JSX-Codes einzubetten.

Beispiel:

<Text>{inputText}</Text> <Button onPress={() => alert('Hi')} />

Erklärung:

  • {} erlauben uns, JavaScript-Logik direkt in die Benutzeroberfläche einzufügen.
  • Ereignis-Handler (wie onPress) erwarten eine JavaScript-Funktion, deshalb verwenden wir geschweifte Klammern.

2. LS 2.2 Sensoren kennen und nutzen

Grundlagen zur Nutzung von Sensoren (z. B. DeviceMotion)

3. LS 2.3 Sensoren implementieren

Bewegungsdaten werden in der App ausgelesen und verarbeitet

4. LS 2.4 Ausgelesene Daten verarbeiten

Analyse und Darstellung der Bewegungsdaten

5. Technikwissen – Kurz erklärt

Schichten-Zuordnung – wichtige Bausteine

In dieser Übersicht sehen Sie, welche typischen Bausteine in React Native zur Präsentations- bzw. Fachschicht gehören. Diese Einordnung hilft Ihnen beim Arbeitsauftrag 2 im Lernschritt 1.1.

Begriff Erklärung Schicht Begründung
Button Anzeige- und Bedienelement für Nutzerinteraktion Präsentationsschicht Sichtbares UI-Element zur Eingabe durch den Nutzer
TouchableOpacity UI-Komponente, die auf Berührung reagiert Präsentationsschicht Reagiert auf Berührung, ohne Logik zu verarbeiten
useState React-Hook zur Zustandsverwaltung Präsentationsschicht Speichert UI-Zustände, reagiert auf Nutzeraktionen
fetch Befehl zum Abruf von Daten aus einem Webservice Fachschicht Teil der Datenverarbeitung bzw. Geschäftslogik
calculateSteps() Funktion zur Berechnung von Schritten (z. B. aus Sensordaten) Fachschicht Verarbeitet Daten – gehört zur Business-Logik
AsyncStorage Lokale Datenspeicherung auf dem Gerät Fachschicht Verwaltung der dauerhaften Daten (z. B. Speicherung von Ergebnissen)

5.1. useEffect – auf Änderungen reagieren

useEffect – auf Änderungen reagieren

Mit useEffect kann Ihre App automatisch etwas tun, wenn sich ein Wert verändert – z. B. wenn sich die Position ändert oder das Spiel beginnt.

Beispiel: Punkte zählen

useEffect(() => {
  if (punkte >= 5) {
    setSpielBeendet(true);
  }
}, [punkte]);
  • Wenn sich punkte ändert, wird die Funktion neu ausgeführt.
  • Die Funktion reagiert nur, wenn punkte sich verändert.

Tipp:

Geben Sie in eckigen Klammern an, auf welche Werte reagiert werden soll – das nennt man Abhängigkeiten.

Merksatz:

useEffect reagiert auf Veränderungen – wie ein Bewegungsmelder im Code.

5.2. Accelerometer – Bewegung erkennen

Accelerometer – Bewegung erkennen

Der Accelerometer ist ein Bewegungssensor im Gerät. Er erkennt, ob das Gerät nach links, rechts, vorne oder hinten geneigt wird.

Beispiel: Sensor starten

import { Accelerometer } from 'expo-sensors';

useEffect(() => {
  const subscription = Accelerometer.addListener(({ x, y }) => {
    console.log(x, y);
  });

  Accelerometer.setUpdateInterval(100);
  return () => subscription.remove();
}, []);

Tipp:

Der Sensor gibt Werte für x, y und z aus. Diese ändern sich je nach Neigung des Geräts.

Merksatz:

Der Accelerometer spürt, wenn sich dein Handy bewegt.

5.3. TextInput – Texte eingeben

 TextInput – Texte eingeben

Mit TextInput können Benutzer:innen Text in ein Feld eingeben – z. B. ihren Namen oder eine Aufgabe.

Beispiel:

const [text, setText] = useState('');

Tipp:

Textfelder brauchen value und onChangeText, um richtig zu funktionieren.

Merksatz:

TextInput ist wie ein digitales Eingabefeld auf Papier.

5.4. Button – auf Klicks reagieren

Button – auf Klicks reagieren

Mit einem Button können Nutzer:innen etwas auslösen – z. B. einen Text anzeigen oder etwas speichern.

Beispiel:

<Button
  title="Klick mich"
  onPress={() => alert("Hallo!")}
/>

Tipp:

Die Aktion wird über onPress ausgeführt – nicht onClick wie im Web!

Merksatz:

Button = Drück mich!

5.5. Flexbox – Elemente anordnen

 Flexbox – Elemente anordnen

Mit Flexbox können Sie steuern, wie Elemente auf dem Bildschirm angeordnet sind – z. B. nebeneinander oder untereinander.

Beispiel:

<View style={{
  flexDirection: 'row',
  justifyContent: 'space-between'
}}>
  <Text>A</Text>
  <Text>B</Text>
</View>

 Tipp:

  • flexDirection: 'row' → Elemente nebeneinander
  • flexDirection: 'column' → Elemente untereinander

 Merksatz:

Flexbox hilft, Ordnung auf dem Bildschirm zu schaffen.

5.6. Zufallszahlen erzeugen mit Math.random()

Zufallszahlen erzeugen mit Math.random()

 In vielen Anwendungen ist es nützlich, mit Zufallszahlen zu arbeiten – z. B. für Spiele, Simulationen oder dynamische Inhalte.

Was macht Math.random()?

Die Funktion Math.random() erzeugt eine Zufallszahl zwischen 0 (inklusive) und 1 (exklusiv). Beispiel:


let zahl = Math.random();  // z. B. 0.368214

Zufallszahlen in einem bestimmten Bereich

Um eine Zufallszahl z. B. zwischen 0 und 100 zu erzeugen:


let zahl = Math.random() * 100;  // z. B. 83.7

Für ganze Zahlen rundet man z. B. mit Math.floor() ab:


let zahl = Math.floor(Math.random() * 100);  // ganzzahlig zwischen 0 und 99

Zufällige Koordinaten erzeugen

Auch Positionen auf dem Bildschirm können zufällig gesetzt werden – z. B. mit:


let x = Math.random() * screenWidth;
let y = Math.random() * screenHeight;

Dabei müssen Ränder mitbedacht werden, z. B. bei der Größe eines Elements:


let x = Math.random() * (screenWidth - 60);

Typischer Fehler

Math.random() gibt keine ganze Zahl zurück! Um ganze Zahlen zu erhalten, brauchen Sie zusätzlich Math.floor() oder Math.round().

5.7. map

Ein Array durchlaufen und dabei neue Elemente erzeugen – mit .map()

Mit der Methode .map() kann man ein Array durchlaufen und für jeden Eintrag ein neues Element erzeugen. Das Ergebnis ist ein neues Array, das genauso viele Elemente enthält wie das ursprüngliche – aber in veränderter Form.

In der App-Entwicklung wird .map() häufig verwendet, um Daten in UI-Elemente zu überführen, z. B. um eine Liste von Texten auszugeben.

Beispiel:
Die gespeicherten Bewegungswerte sollen als Liste angezeigt werden:


bewegungen.map((wert, index) => (
  <Text key={index}>
    {index + 1}: {wert}
  </Text>
))

Jeder Wert im Array bewegungen wird dabei zu einem eigenen <Text>-Element. Der key sorgt dafür, dass React die Liste effizient verwalten kann.

Hinweis: .map() verändert das ursprüngliche Array nicht, sondern gibt ein neues Array mit den bearbeiteten Elementen zurück.

 Die Kombination aus .map() und JSX ist in React die Standardmethode, um Listen von Daten in sichtbare Inhalte umzuwandeln.

5.8. useState

useRef – Referenzen auf Komponenten oder Werte

Mit dem React-Hook useRef() können Sie veränderliche Werte speichern, die beim Aktualisieren des UI nicht verloren gehen – zum Beispiel Zeitgeber (setInterval) oder Sensor-Abos.

const intervalRef = useRef(null);

Der aktuelle Wert wird über intervalRef.current angesprochen. Beispiel für das Stoppen eines Countdowns:

clearInterval(intervalRef.current);

Auch für den Zugriff auf Sensoren wie den Accelerometer wird useRef verwendet, um später z. B. den Sensor wieder zu deaktivieren:


sensorRef.current = Accelerometer.addListener(({ x, y, z }) => {
  // ...
});

sensorRef.current.remove(); // Deaktiviert den Sensor

Tipp: useRef ist ideal, wenn Sie eine Art "Behälter" für veränderliche Objekte brauchen, die nicht jedes Mal neu gerendert werden sollen – z. B. laufende Zeitgeber oder Sensor-Abos.


setState(prev => ...) – Vorherigen Zustand sicher aktualisieren

Wenn Sie eine State-Variable aktualisieren möchten, die auf ihrem bisherigen Zustand basiert (z. B. ein Array erweitern), ist es sinnvoll, die sogenannte funktionale Schreibweise zu verwenden:


setBewegungen(prev => [...prev, neuerWert]);

Dadurch wird sichergestellt, dass Sie immer den aktuellen Zustand erhalten – selbst wenn andere Updates gleichzeitig laufen. Diese Methode ist besonders nützlich bei Sensorwerten oder anderen schnellen Updates.

Tipp: Vermeiden Sie bei Arrays die direkte Verwendung von bewegungen in setBewegungen([...bewegungen, neuerWert]), da es sein kann, dass bewegungen nicht den aktuellsten Stand enthält.

5.9. Array

 Array

Ein Array ist eine geordnete Liste von Werten. Es wird in JavaScript mit eckigen Klammern geschrieben, z. B.:

const zahlen = [1, 2, 3, 4];

Jeder Wert hat eine Position (Index). Man kann Werte hinzufügen, löschen oder über Methoden wie map() oder slice() bearbeiten.

Wichtig: Die Methode push() verändert das Array direkt, aktualisiert aber nicht den React-State korrekt. Verwenden Sie deshalb den Spread-Operator (siehe unten).

5.10. Spread-Operator

 Spread-Operator ...

Der Spread-Operator ... wird verwendet, um ein Array „aufzufächern“ – also alle Elemente einzeln in ein neues Array zu übernehmen. Beispiel:

const neueListe = [...bewegungen, neuerWert];

So wird ein neues Array erzeugt, das alle bisherigen Bewegungen enthält, ergänzt um den neuen Wert.

5.11. .slice()

.slice() – Teilbereich extrahieren

Die Methode .slice() erzeugt eine Kopie eines Teilbereichs eines Arrays. Beispiel:

bewegungen.slice(-100)

Das erzeugt ein neues Array mit den letzten 100 Einträgen des ursprünglichen Arrays. Das Original bleibt dabei unverändert.

5.12. .map()

.map() – Array durchlaufen und Elemente erzeugen

Mit .map() kann ein Array durchlaufen und für jeden Eintrag ein neues Element erzeugt werden. Beispiel für die Anzeige von Bewegungswerten:


bewegungen.map((wert, index) => (
  
    {index + 1}: {wert}
  
))

Tipp: Verwenden Sie immer einen eindeutigen key (z. B. index), um Warnungen im React Native-Log zu vermeiden.

5.13. useState

useState – Zustände verwalten

Mit useState() legt man in React Native einen sogenannten State an – also eine Variable, die sich während der Laufzeit ändern kann und die das UI automatisch aktualisiert. Beispiel:

const [bewegungen, setBewegungen] = useState([]);

bewegungen enthält den aktuellen Zustand, setBewegungen() ändert ihn.


 Beispiel aus der Praxis (z. B. Bewegung erkennen):

const [bewegungErkannt, setBewegungErkannt] = useState(false);

bewegungErkannt speichert, ob ein Ereignis eingetreten ist. Mit setBewegungErkannt(true) wird der Zustand geändert.

 Anzeige abhängig vom Zustand:

{bewegungErkannt && <Text>🚨 Bewegung erkannt!</Text>}

Der Text erscheint nur, wenn bewegungErkannt den Wert true hat.

Merksatz:

„Mit useState merkt sich React, was sich im Laufe der Zeit verändert.“

5.14. useRef

useRef – Referenzen auf Komponenten oder Werte

Mit dem React-Hook useRef() können Sie veränderliche Werte speichern, die beim Aktualisieren des UI nicht verloren gehen – zum Beispiel Zeitgeber (setInterval) oder Sensor-Abos.

const intervalRef = useRef(null);

Der aktuelle Wert wird über intervalRef.current angesprochen. Beispiel für das Stoppen eines Countdowns:

clearInterval(intervalRef.current);

Auch für den Zugriff auf Sensoren wie den Accelerometer wird useRef verwendet, um später z. B. den Sensor wieder zu deaktivieren:


sensorRef.current = Accelerometer.addListener(({ x, y, z }) => {
  // ...
});

sensorRef.current.remove(); // Deaktiviert den Sensor

Tipp: useRef ist ideal, wenn Sie eine Art "Behälter" für veränderliche Objekte brauchen, die nicht jedes Mal neu gerendert werden sollen – z. B. laufende Zeitgeber oder Sensor-Abos.

5.15. useCallback

useCallback() – Funktionen bei Änderungen neu erzeugen

Der React-Hook useCallback() sorgt dafür, dass eine Funktion nur dann neu erstellt wird, wenn sich eine ihrer Abhängigkeiten verändert. Das ist wichtig, wenn Sie die Funktion in einem useEffect verwenden oder an Komponenten weitergeben möchten, ohne dass unnötige Aktualisierungen passieren.


const startMessung = useCallback(() => {
  setStatus('measuring');
  // ... weitere Logik ...
}, [status]);

Tipp: useCallback ist besonders nützlich, wenn Sie Funktionen an useEffect oder andere Hooks übergeben müssen und dabei keine unnötigen Wiederholungen auslösen möchten.

5.16. TouchableOpacity – Berührbare UI-Komponente

TouchableOpacity – Berührbare UI-Komponente

Mit TouchableOpacity können Nutzer:innen auf Elemente tippen, die nicht wie klassische Buttons aussehen. Sie wird oft verwendet, um Bilder, Icons oder eigene Designs klickbar zu machen.

<TouchableOpacity onPress={() => alert("Gedrückt!")}>
  <Text>Ich bin berührbar</Text>
</TouchableOpacity>

Tipp:
TouchableOpacity kann wie ein Button verwendet werden – Sie haben aber mehr Freiheit beim Design (z. B. Icons, Bilder oder Textkombinationen).

Merksatz:
TouchableOpacity macht jedes Element „antippbar“.

5.17. fetch – Daten aus dem Internet abrufen

fetch – Daten aus dem Internet abrufen

Mit fetch() können Sie Daten von einer externen Quelle (z. B. einer API) abrufen – z. B. Schrittziele oder Wetterdaten.

fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => console.log(data));

Tipp:
Verwenden Sie async/await, um den Code übersichtlicher zu gestalten.

const ladeDaten = async () => {
  const response = await fetch('...');
  const daten = await response.json();
  setDaten(daten);
};

Merksatz:
Mit fetch() holen Sie sich Daten von außen in Ihre App.

5.18. AsyncStorage – Daten lokal speichern

AsyncStorage – Daten lokal speichern

AsyncStorage erlaubt es, kleine Datenmengen dauerhaft auf dem Gerät zu speichern – z. B. gespeicherte Aktivitäten oder Nutzer:innen-Einstellungen.

import AsyncStorage from '@react-native-async-storage/async-storage';

await AsyncStorage.setItem('meinWert', '123');
const wert = await AsyncStorage.getItem('meinWert');

Tipp:
Daten bleiben auch nach dem Schließen der App erhalten – nützlich für den „Speichern“-Effekt.

Merksatz:
Mit AsyncStorage merkt sich Ihre App Dinge – auch nach dem Ausschalten.