Mettere tutto insieme: una schermata profilo
Uniamo i pezzi in una schermata profilo realistica: header a onda, avatar circolare sovrapposto con Stack, e una griglia di immagini arrotondate.
Nota su Stack: l'avatar viene posizionato con Positioned e sporge oltre l'header; per questo diamo alla Stack un'altezza sufficiente e usiamo clipBehavior: Clip.none se vuoi permettere lo sbordo.
Consigli finali
- ogni Clip ha un costo: non annidarne più del necessario
- preferisci
const dove possibile per ridurre le ricostruzioni
- verifica il risultato su schermi diversi: le forme di
ClipPath dipendono da size, quindi si adattano automaticamente
- per icone e loghi vettoriali complessi valuta un SVG invece di un
CustomClipper
class ProfilePage extends StatelessWidget {
const ProfilePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
padding: EdgeInsets.zero,
children: [
SizedBox(
height: 220,
child: Stack(
clipBehavior: Clip.none,
alignment: Alignment.topCenter,
children: [
ClipPath(
clipper: WaveClipper(),
child: Container(height: 170, color: Colors.indigo),
),
Positioned(
bottom: 0,
child: Container(
padding: const EdgeInsets.all(4),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
),
child: const CircleAvatar(
radius: 50,
backgroundImage:
NetworkImage('https://picsum.photos/300'),
),
),
),
],
),
),
const SizedBox(height: 12),
const Center(
child: Text('Giulia Rossi',
style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold)),
),
const SizedBox(height: 16),
GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.all(16),
itemCount: 6,
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
),
itemBuilder: (context, index) => ClipRRect(
borderRadius: BorderRadius.circular(14),
child: Image.network(
'https://picsum.photos/200?random=$index',
fit: BoxFit.cover,
),
),
),
],
),
);
}
}
Risultato atteso
Impostando `home: const ProfilePage()` vedi una schermata profilo con header curvo indaco, avatar circolare bordato di bianco a cavallo dell'onda e una griglia 3x3 di miniature con angoli arrotondati.