Creating an Instruction UI Screen in Flutter Application

Creating an Instruction UI Screen in Flutter with source code – When designing a user-friendly instruction screen in a Flutter application, it’s essential to focus on clear communication, intuitive design, and seamless navigation. This guide will walk you through creating a well-structured Instruction UI Screen using Flutter and GetX while following best practices for UI/UX design.

<img decoding=

1. Understanding the Instruction Screen

The Instruction UI Screen is designed to guide users through a process step-by-step before they proceed to the next screen. In this example, the instruction screen provides guidelines for using a stress measurement AI feature.

Key Features of the Screen:

✅ Gradient background for a modern look
✅ Stepwise instructions with icons and colors
✅ Permission handling for camera access
✅ A call-to-action button for user progression


2. Implementing the UI Screen in Flutter

2.1. Setting Up the Screen

The MeasureInstructionScreen class extends StatefulWidget to manage UI state. The background uses a LinearGradient to create a smooth transition from light blue to steel blue.

Container(
  decoration: const BoxDecoration(
    gradient: LinearGradient(
      colors: [Color(0xFFB0E0E6), Color.fromARGB(255, 136, 169, 198)],
      begin: Alignment.topCenter,
      end: Alignment.bottomCenter,
    ),
  ),
  child: Scaffold(
    backgroundColor: Colors.transparent,
    appBar: AppBar(
      title: Text(
        "Instruction",
        style: TextStyle(fontSize: 16, color: Colors.black, fontWeight: FontWeight.w600),
      ),
    ),
  ),
);

2.2. Adding Instruction Steps

Each instruction step is displayed using a custom instruction tile, providing:
✔ A step number
✔ A relevant icon
✔ A short description

Widget buildInstructionTile({
  required String step,
  required String imagePath,
  required String instruction,
  required Color bgborderColor,
  required Color borderColor,
  required Color cardborderColor,
}) {
  return CustomPaint(
    painter: DottedBorderPainterWidget(color: borderColor),
    child: Container(
      padding: const EdgeInsets.all(20),
      decoration: BoxDecoration(
        color: cardborderColor,
        borderRadius: BorderRadius.circular(10),
      ),
      child: Row(
        children: [
          Image.asset(imagePath, width: 40, height: 40, color: bgborderColor),
          const SizedBox(width: 10),
          Expanded(
            child: Text(instruction, style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500)),
          ),
        ],
      ),
    ),
  );
}

🔹 Each step has a unique color for better differentiation:

  • Step 1: Red (⚠️ Camera Access)
  • Step 2: Green (📏 Maintain Distance)
  • Step 3: Amber (📸 Keep Face Steady)

2.3. Handling Camera Permission

Before proceeding, users must allow camera access. The app handles permission requests using the permission_handler package.

final status = await Permission.camera.status;

if (status == PermissionStatus.permanentlyDenied) {
  Utility.showToast("Go to Settings to enable camera access.");
} else if (status != PermissionStatus.granted) {
  await Permission.camera.request().then((value) {
    if (value != PermissionStatus.granted) {
      Navigator.of(context).pop();
    } else {
      Navigator.pushNamed(context, AppRoutes.stressMeasureScreen);
    }
  });
} else {
  Navigator.pushNamed(context, AppRoutes.stressMeasureScreen);
}

2.4. Adding a Call-to-Action Button

A Green Button at the bottom prompts users to start the process.

GreenButton(
  onPressed: () {
    Navigator.pushNamed(context, AppRoutes.stressMeasureScreen);
  },
  height: 6.h,
  width: 100.w,
  borderRadius: BorderRadius.circular(6),
  child: Text(
    "Ready? Go Ahead!!",
    style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white),
  ),
);

Complete Code

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:sizer/sizer.dart';
import 'package:filename/routes/routes.dart';
import 'package:filename/services/utility.dart';
import 'package:filename/ui/screens/stressMeasureAI/StressReportScreen/widget/dottedborderWidget.dart';
import 'package:filename/widgets_constants/appbars/app-bar.dart';

class MeasureInstructionScreen extends StatefulWidget {
  const MeasureInstructionScreen({super.key});

  @override
  State<MeasureInstructionScreen> createState() =>
      _MeasureInstructionScreenState();
}

class _MeasureInstructionScreenState extends State<MeasureInstructionScreen> {
  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: const BoxDecoration(
        gradient: LinearGradient(
          colors: [
            Color(0xFFB0E0E6), // Light blue top
            Color.fromARGB(255, 136, 169, 198) // Steel blue bottom
          ],
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
        ),
      ),
      child: Scaffold(
        backgroundColor: Colors.transparent,
        appBar: AppBar(
          title: SizedBox(
            child: Text(
              "Instruction",
              style: const TextStyle(
                  fontSize: 16,
                  color: Colors.black,
                  fontWeight: FontWeight.w600),
            ),
          ),
          isLandingScreen: false,
          isVideoCallScreen: true,
        ),
        body: SingleChildScrollView(
          child: Padding(
            padding:
                const EdgeInsets.only(left: 12, right: 12, top: 15, bottom: 15),
            child: Stack(
              children: [
                Padding(
                  padding:
                      const EdgeInsets.only(left: 25, right: 15, bottom: 10),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Center(
                        child: Text(
                          "How it works?".tr,
                          style: const TextStyle(
                              color: Colors.black,
                              fontSize: 17,
                              fontWeight: FontWeight.w600),
                          textAlign: TextAlign.center,
                        ),
                      ),
                      const SizedBox(height: 30),
                      Text(
                        "It will take around 8-10 Seconds for the system to gather the data to measure your stress!"
                            .tr,
                        style: TextStyle(fontSize: 15),
                      ),
                      const SizedBox(height: 30),
                      buildInstructionTile(
                          bgborderColor: Colors.redAccent,
                          cardborderColor: Color(0xFFFFCDD2), // Light red
                          step: "01",
                          borderColor: Colors.redAccent,
                          imagePath: 'assets/images/stress2.png',
                          instruction: "Allow Device Camera Access".tr),
                      const SizedBox(height: 45),
                      buildInstructionTile(
                        bgborderColor: Colors.green,
                        cardborderColor: Color(0xFFC8E6C9), // Light green
                        step: "02",
                        borderColor: Colors.green,
                        imagePath: 'assets/images/stress4.png',
                        instruction:
                            "Keep a distance of around 12-15 inches from your mobile"
                                .tr,
                      ),
                      const SizedBox(height: 45),
                      buildInstructionTile(
                        bgborderColor: Colors.amber,
                        cardborderColor: Color(0xFFFFF9C4), // Light yellow
                        step: "03",
                        borderColor: Colors.amber,
                        imagePath: 'assets/images/stress1.png',
                        instruction:
                            "Keep your face in the centre and be steady".tr,
                      ),
                      const SizedBox(height: 40),

                      Center(
                        child: GreenButton(
                          onPressed: () async {
                            final status = await Permission.camera.status;

                            if (status == PermissionStatus.permanentlyDenied) {
                              Utility.showToast(
                                  "User has previously denied the camera access request. Go to Settings to enable camera access."
                                      .tr);
                            } else if (status != PermissionStatus.granted) {
                              await Permission.camera.request().then((value) {
                                if (value != PermissionStatus.granted) {
                                  Navigator.of(context).pop();
                                } else {
                                  Navigator.pushNamed(
                                      context, AppRoutes.stressMeasureScreen);
                                }
                              });
                            } else {
                              if (context.mounted) {
                                Navigator.pushNamed(
                                    context, AppRoutes.stressMeasureScreen);
                              }
                            }
                          },
                          height: 6.h,
                          width: 100.w,
                          borderRadius: BorderRadius.circular(6),
                          child: Text(
                            "Ready? Go Ahead!!".tr,
                            style: TextStyle(
                                fontSize: 16,
                                fontWeight: FontWeight.w600,
                                color: Colors.white),
                          ),
                        ),
                      ),
                      const SizedBox(height: 20),
                    ],
                  ),
                ),
                Positioned(
                  top: 100,
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.start,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Container(
                        width: 40,
                        height: 40,
                        decoration: BoxDecoration(
                          color: Colors.red,
                          borderRadius: BorderRadius.circular(5),
                          shape: BoxShape.rectangle,
                        ),
                        alignment: Alignment.center,
                        child: const Text(
                          "01",
                          style: TextStyle(
                            color: Colors.white,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                      ),
                      const SizedBox(
                        height: 85,
                      ),
                      Container(
                        width: 40,
                        height: 40,
                        decoration: BoxDecoration(
                          color: Colors.green,
                          borderRadius: BorderRadius.circular(5),
                          shape: BoxShape.rectangle,
                        ),
                        alignment: Alignment.center,
                        child: const Text(
                          "02",
                          style: TextStyle(
                            color: Colors.white,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                      ),
                      const SizedBox(
                        height: 87,
                      ),
                      Container(
                        width: 40,
                        height: 40,
                        decoration: BoxDecoration(
                          color: Colors.amber,
                          borderRadius: BorderRadius.circular(5),
                          shape: BoxShape.rectangle,
                        ),
                        alignment: Alignment.center,
                        child: const Text(
                          "03",
                          style: TextStyle(
                            color: Colors.white,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                      ),
                      Platform.isIOS
                          ? Column(
                              children: [
                                const SizedBox(
                                  height: 80,
                                ),
                                Container(
                                  width: 40,
                                  height: 40,
                                  decoration: BoxDecoration(
                                    color: Colors.red,
                                    borderRadius: BorderRadius.circular(5),
                                    shape: BoxShape.rectangle,
                                  ),
                                  alignment: Alignment.center,
                                  child: const Text(
                                    "04",
                                    style: TextStyle(
                                      color: Colors.white,
                                      fontWeight: FontWeight.bold,
                                    ),
                                  ),
                                ),
                              ],
                            )
                          : SizedBox.shrink(),

                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

// instruction widget
  Widget buildInstructionTile({
    required String step,
    required String imagePath,
    required String instruction,
    required Color bgborderColor,
    required Color borderColor,
    required Color cardborderColor,
  }) {
    return CustomPaint(
      painter: DottedBorderPainterWidget(color: borderColor),
      child: Container(
        padding:
            const EdgeInsets.only(left: 10, right: 10, bottom: 20, top: 20),
        decoration: BoxDecoration(
          color: cardborderColor,
          borderRadius: BorderRadius.circular(10),
        ),
        child: Row(
          children: [
            const SizedBox(width: 10),
            Image.asset(
              imagePath,
              width: 40,
              height: 40,
              fit: BoxFit.contain,
              color: bgborderColor,
            ),
            const SizedBox(width: 10),
            Expanded(
              child: Text(
                instruction,
                style:
                    const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

// button widget
class GreenButton extends StatelessWidget {
  const GreenButton({
    super.key,
    required this.child,
    this.onPressed,
    this.height,
    this.width,
    this.backgroundColor,
    this.padding,
    this.border,
    this.borderRadius,
    this.alignment,
    this.margin,
  });

  final double? height;
  final double? width;
  final Widget child;
  final Color? backgroundColor;
  final VoidCallback? onPressed;
  final EdgeInsets? padding;
  final Border? border;
  final BorderRadius? borderRadius;
  final Alignment? alignment;
  final EdgeInsets? margin;

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      style: ButtonStyle(
        backgroundColor:
            MaterialStateProperty.all(backgroundColor ?? Colors.greenAccent),
        shape: MaterialStateProperty.all<RoundedRectangleBorder>(
            RoundedRectangleBorder(
          borderRadius: borderRadius ?? BorderRadius.circular(30.0),
        )),
        // side: MaterialStateProperty.all<BorderSide>(
        //   BorderSide(
        //       color: backgroundColor ??
        //           SolhColors.primary_green), // Adjust border color here
        // ),
      ),
      onPressed: onPressed,
      child: Container(
        height: height ?? 7.h,
        width: width ?? 180,
        padding: const EdgeInsets.all(1),
        child: Center(child: child),
      ),
    );
  }
}


3. Enhancing UI/UX for Better User Experience

  • Use Animations 🎞: Apply simple animations for better engagement.
  • Provide Feedback 🔔: Show a loading indicator when checking permissions.
  • Optimize for Accessibility ♿: Ensure the text is readable with good contrast.

Conclusion

Creating an Instruction UI Screen in Flutter involves designing a clear, stepwise guide that is easy to follow. By implementing visually appealing UI elements, permission handling, and a call-to-action button, we ensure an intuitive user experience.

🚀 Now you’re ready to build an instruction screen for any Flutter app! 🎯

Related Articles

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top