Avatar in React Native
Avatar
~9 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026
Ein Avatar zeigt ein rundes Profilbild – oder, falls keines vorhanden ist, einen Platzhalter mit den Initialen des Benutzernamens. Beide Fälle lassen sich in EINER wiederverwendbaren Komponente abdecken.
1. Beschreibung
Der runde Ausschnitt entsteht durch borderRadius in exakter Höhe des halben Durchmessers (width/height: 48 → borderRadius: 24). Für den Initialen-Fallback wird der Benutzername in seine Wörter zerlegt und der jeweils erste Buchstabe verwendet.
2. Kurzes Beispiel
<Image
source={{ uri: bildUrl }}
style={{ width: 48, height: 48, borderRadius: 24 }}
/>3. Komplettes Projekt: Kontaktliste mit Avataren
npx create-expo-app avatar-demo
cd avatar-demoimport { View, Image, Text, StyleSheet } from 'react-native';
const FARBEN = ['#2563eb', '#16a34a', '#dc2626', '#9333ea', '#ea580c'];
function initialenVon(name) {
return name
.trim()
.split(/\s+/)
.slice(0, 2)
.map((wort) => wort[0]?.toUpperCase())
.join('');
}
function farbeVon(name) {
const summe = [...name].reduce((acc, zeichen) => acc + zeichen.charCodeAt(0), 0);
return FARBEN[summe % FARBEN.length];
}
function Avatar({ name, bildUrl, groesse = 48 }) {
const stil = { width: groesse, height: groesse, borderRadius: groesse / 2 };
if (bildUrl) {
return <Image source={{ uri: bildUrl }} style={stil} />;
}
return (
<View style={[stil, styles.platzhalter, { backgroundColor: farbeVon(name) }]}>
<Text style={[styles.initialen, { fontSize: groesse * 0.4 }]}>
{initialenVon(name)}
</Text>
</View>
);
}
const styles = StyleSheet.create({
platzhalter: { alignItems: 'center', justifyContent: 'center' },
initialen: { color: 'white', fontWeight: 'bold' },
});
export default Avatar;import { View, Text, FlatList, StyleSheet } from 'react-native';
import Avatar from './components/Avatar';
const KONTAKTE = [
{ id: '1', name: 'Anna Berger', bildUrl: 'https://i.pravatar.cc/150?img=5' },
{ id: '2', name: 'Mehmet Yildiz', bildUrl: null },
{ id: '3', name: 'Sophie Klein', bildUrl: null },
];
export default function App() {
return (
<FlatList
data={KONTAKTE}
keyExtractor={(item) => item.id}
contentContainerStyle={styles.liste}
renderItem={({ item }) => (
<View style={styles.zeile}>
<Avatar name={item.name} bildUrl={item.bildUrl} />
<Text style={styles.name}>{item.name}</Text>
</View>
)}
/>
);
}
const styles = StyleSheet.create({
liste: { paddingTop: 60, paddingHorizontal: 16 },
zeile: { flexDirection: 'row', alignItems: 'center', paddingVertical: 10 },
name: { marginLeft: 12, fontSize: 16 },
});4. Erklärung
bildUrl ? <Image .../> : <View .../>– die Komponente entscheidet SELBST, ob ein echtes Bild oder der Initialen-Platzhalter gerendert wird, der Aufrufer muss das nicht wissen.farbeVon(name)erzeugt eine deterministische (immer gleiche) Farbe pro Namen – über die Summe der Zeichencodes modulo Farbanzahl, statt eine zufällige Farbe bei jedem Render.groesse / 2statt eines festen Werts macht die Komponente wiederverwendbar für verschiedene Avatar-Größen (z.B. klein in einer Liste, groß auf einem Profil-Screen) – EINgroesse-Prop steuert Breite, Höhe UND Rundung gemeinsam.[...name].reduce(...)stattname.charCodeAtdirekt über den String, um auch mit Namen zu funktionieren, die aus Zeichen außerhalb des Basic-Latin-Bereichs bestehen (Spread-Operator zerlegt korrekt in einzelne Zeichen).