openplanning

Bài thực hành Flutter thiết kế trang profile (2)

  1. UserAvatarSection
  2. SocialButtonsSection
  3. UserInfoSection
  4. ProfileListItemsSection
  5. HomeScreen
Trong bài thực hành Flutter này chúng ta sẽ thiết kế trang Profile giống như hình minh hoạ dưới đây:
Các file ảnh sử dụng trong bài học này:
Các bài viết liên quan:
  • Khoá học Flutter miễn phí cho người mới bắt đầu
  • Bài thực hành Flutter thiết kế trang profile
  • Bài thực hành Flutter thiết kế giao diện trang hồ sơ (profile)

1. UserAvatarSection

user_avatar_section.dart
import 'package:flutter/material.dart';

BoxDecoration avatarDecoration = BoxDecoration(
  shape: BoxShape.circle,
  color: Colors.grey.shade200,
  boxShadow: const [
    BoxShadow(
      color: Colors.white,
      offset: Offset(10, 10),
      blurRadius: 10,
    ),
    BoxShadow(
      color: Colors.white,
      offset: Offset(10, -10),
      blurRadius: 10,
    ),
    BoxShadow(
      color: Colors.white,
      offset: Offset(-10, 10),
      blurRadius: 10,
    ),
    BoxShadow(
      color: Colors.white,
      offset: Offset(-10, -10),
      blurRadius: 10,
    ),
  ],
);

class UserAvatarSection extends StatelessWidget {
  final String imageUrl;
  const UserAvatarSection({super.key, required this.imageUrl});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 120,
      height: 120,
      padding: const EdgeInsets.all(8),
      decoration: avatarDecoration,
      child: Container(
        decoration: avatarDecoration,
        padding: const EdgeInsets.all(3),
        child: CircleAvatar(
          backgroundColor: Colors.white,
          backgroundImage: NetworkImage(imageUrl),
        ),
      ),
    );
  }
}
  • Flutter BoxShadow

2. SocialButtonsSection

Viết lớp CustomSocialButton đại diện cho một button và đặt chúng trên một Row.
social_buttons_section.dart
import 'package:flutter/material.dart';

class SocialButtonsSection extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        CustomSocialButton(
          color: const Color(0xFF102397),
          iconName: 'facebook.png',
          onPressed: () {},
        ),
        CustomSocialButton(
          color: const Color(0xFFff4f38),
          iconName: 'googleplus.png',
          onPressed: () {},
        ),
        CustomSocialButton(
          color: const Color(0xFF38A1F3),
          iconName: 'twitter.png',
          onPressed: () {},
        ),
        CustomSocialButton(
          color: const Color(0xFF2867B2),
          iconName: 'linkedin.png',
          onPressed: () {},
        )
      ],
    );
  }
}

class CustomSocialButton extends StatelessWidget {
  final Color color;
  final String iconName;
  final Function() onPressed;

  const CustomSocialButton({
    super.key,
    required this.color,
    required this.iconName,
    required this.onPressed,
  });

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(left: 20.0),
      child: Container(
        width: 45.0,
        height: 45.0,
        decoration: BoxDecoration(shape: BoxShape.circle, color: color),
        child: RawMaterialButton(
          shape: const CircleBorder(),
          onPressed: onPressed,
          child: Image.asset(
            'my-static-rs/icon/$iconName',
            width: 24,
            height: 24,
          ),
        ),
      ),
    );
  }
}

3. UserInfoSection

user_info_section.dart
import 'package:flutter/material.dart';

class UserInfoSection extends StatelessWidget {
  final String title;
  final String subtitle;
  final String description;
  const UserInfoSection({
    super.key,
    required this.title,
    required this.subtitle,
    required this.description,
  });
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text(
          title,
          style: const TextStyle(
            fontSize: 30,
            fontWeight: FontWeight.w700,
          ),
        ),
        Text(
          subtitle,
          style: const TextStyle(fontWeight: FontWeight.w300),
        ),
        const SizedBox(height: 15),
        Text(
          description,
          textAlign: TextAlign.center,
          style: const TextStyle(fontSize: 20),
        ),
      ],
    );
  }
}

4. ProfileListItemsSection

profile_list_items_section.dart
import 'package:flutter/material.dart';

class ProfileListItemsSection extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return const Column(
      children: <Widget>[
        ProfileListItem(
          iconData: Icons.shield_outlined,
          text: 'Privacy',
        ),
        ProfileListItem(
          iconData: Icons.history,
          text: 'Purchase History',
        ),
        ProfileListItem(
          iconData: Icons.question_answer_outlined,
          text: 'Help & Support',
        ),
        ProfileListItem(
          iconData: Icons.settings,
          text: 'Settings',
        ),
        ProfileListItem(
          iconData: Icons.person_add_alt,
          text: 'Invite a Friend',
        ),
        ProfileListItem(
          iconData: Icons.logout,
          text: 'Logout',
          hasNavigation: false,
        ),
      ],
    );
  }
}

class ProfileListItem extends StatelessWidget {
  final IconData iconData;
  final String text;
  final bool hasNavigation;

  const ProfileListItem({
    Key? key,
    required this.iconData,
    required this.text,
    this.hasNavigation = true,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 0),
      child: ListTile(
        shape: const RoundedRectangleBorder(
          borderRadius: BorderRadius.all(
            Radius.circular(30),
          ),
        ),
        tileColor: Colors.grey.shade300,
        leading: Icon(
          iconData,
          size: 30,
        ),
        title: Text(
          text,
          style: const TextStyle(
            fontSize: 18,
            fontWeight: FontWeight.w600,
          ),
        ),
        trailing: const Icon(
          Icons.arrow_forward_ios_rounded,
          size: 24,
        ),
        onTap: () {},
      ),
    );
  }
}

5. HomeScreen

home_screen.dart
import 'package:flutter/material.dart';

import 'profile_list_items_section.dart';
import 'social_buttons_section.dart';
import 'user_avatar_section.dart';
import 'user_info_section.dart';

class MyHomePage extends StatelessWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey.shade200,
      appBar: AppBar(
        title: const Text("Profile"),
        actions: [
          TextButton(
            onPressed: () {},
            child: Icon(
              Icons.menu,
              color: Colors.grey.shade600,
            ),
          ),
        ],
      ),
      body: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.all(20),
          child: Column(
            children: <Widget>[
              const UserAvatarSection(
                imageUrl:
                    'https://raw.githubusercontent.com/o7planning/rs/master/flutter/users/user1.jpeg',
              ),
              const SizedBox(height: 30),
              SocialButtonsSection(),
              const SizedBox(height: 30),
              const UserInfoSection(
                title: 'chromicle',
                subtitle: '@amFOSS',
                description:
                    'Mobile App Developer and Open source enthusiastic',
              ),
              const SizedBox(height: 30),
              ProfileListItemsSection(),
            ],
          ),
        ),
      ),
    );
  }
}
main.dart
import 'package:flutter/material.dart';

import 'home_screen.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

Các hướng dẫn lập trình Flutter

Show More