Facebook Twitter Instagram
    DeepCrazyWorld
    Facebook Twitter Instagram Pinterest YouTube
    • FLUTTER
      • FLUTTER APP
        • QRCode
        • Quiz App
        • Chat GPT
        • PDF App
        • News App
        • Fitness App
        • Weather App
        • BMI Calculator
        • GAME APP
        • Ecommerce App
        • wallpaper App
        • Finance app
        • Chat App
        • Wallet App
        • Taxi App
        • Quran app
        • Music player app
      • FLUTTER UI
        • Splash Screen
        • Onboarding Screen
        • Login Screen
        • Card Design
        • Drawer
    • PROJECT
      • Android Projects
      • College Projects
      • FLUTTER APP
      • Project Ideas
      • PHP Projects
      • Python Projects
    • SOURCE CODE
    • ANDROID
      • ANDROID APP
      • GAME APP
      • ANDROID STUDIO
    • MCQ
      • AKTU MCQ
        • RPA MCQ
        • COA MCQ
        • HPC MCQ
        • SPM MCQ
        • Renewable Energy All MCQ
        • Data Compression MCQ
        • Data Structure MCQ
        • Digital Image Processing MCQ
        • Software Engineering MCQ
        • Machine Learning MCQ
        • Artificial Intelligence MCQ
      • D PHARMA MCQ
        • Pharmaceutics – I MCQ
        • Pharmacognosy MCQ
        • Pharmaceutical Chemistry MCQ
        • Biochemistry and Clinical Pathology MCQ
        • Human Anatomy and Physiology MCQ
        • Heath Education and Community Pharmacy MCQ
    • INTERVIEW QUESTIONS
      • Flutter Interview Questions
      • INTERVIEW QUESTIONS
      • Python Interview Questions
      • Coding ninjas solution
    • MORE
      • WORDPRESS
        • SEO
        • TOP 10 WORDPRESS THEME
      • PRODUCTIVITY
      • Program
      • QUOTES
    DeepCrazyWorld
    Home»FLUTTER»Implementing a Dynamic FAQ Screen UI in Flutter Using ExpansionTile
    FLUTTER

    Implementing a Dynamic FAQ Screen UI in Flutter Using ExpansionTile

    DeepikaBy DeepikaMarch 29, 2025Updated:March 29, 2025No Comments5 Mins Read

    FAQs (Frequently Asked Questions) are a crucial part of any application, providing users with instant answers to common queries. In this guide, we will implement an FAQ screen in Flutter using the ExpansionTile widget, making it both visually appealing and functionally efficient. This implementation will support dynamic data retrieval, ensuring a seamless user experience.

    <img decoding=

    Table of Contents

    Toggle
      • Overview of the Implementation
      • Breaking Down the Code
        • 1. Initializing the FAQ Screen
        • 2. Structuring the UI
        • 3. Handling Loading and No Data Cases
        • 4. Displaying FAQs Using ExpansionTile
      • 5. Controller Implementation
    • Output
    • Complete code
      • Why Use ExpansionTile for FAQs?
      • Conclusion
      • Related Articles

    Overview of the Implementation

    Our approach involves using:

    • ExpansionTile to create collapsible sections for questions and answers.
    • ListView.builder to dynamically generate the list of FAQs.
    • Obx (from GetX state management) to handle state updates dynamically.
    • Gradient background and default Flutter styles for an enhanced UI.
    • API call integration to fetch FAQs dynamically from a backend.

    Breaking Down the Code

    1. Initializing the FAQ Screen

    The CoursesFaqScreeen widget is a StatefulWidget since we need to fetch data and update the UI accordingly. The CourseFaqController is used to manage the API calls and store FAQ data.

    final CourseFaqController courseFaqController = Get.find();

    In the initState method, we call the API using the getCourseFaq function with the course ID passed via widget.args:

    @override
    void initState() {
      courseFaqController.getCourseFaq(widget.args['courseId']);
      super.initState();
    }

    This ensures that FAQs are fetched as soon as the screen loads.

    2. Structuring the UI

    The Scaffold widget contains an AppBar with the title “FAQs”. The background is set using a gradient for a smooth visual effect.

    body: Container(
      height: double.infinity,
      decoration: const BoxDecoration(
        gradient: LinearGradient(
          colors: [
            Colors.blueAccent,
            Colors.lightBlue,
          ],
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
        ),
      ),
    <img loading=

    3. Handling Loading and No Data Cases

    We use Obx to listen to changes in courseFaqController.isLoading. If loading is in progress, we show a loader. If no FAQs are available, a “No Data Found” widget is displayed.

    child: Obx(() => courseFaqController.isLoading.value
        ? Center(child: CircularProgressIndicator())
        : courseFaqController.faqs.isEmpty
            ? Center(child: Text("No FAQs Available"))
            : ListView.builder(

    4. Displaying FAQs Using ExpansionTile

    Each FAQ is displayed as an expandable section. The ExpansionTile takes the question as its title and the answer inside a ListTile that is decorated with a light gray background.

    child: ExpansionTile(
      title: Text(
        courseFaqController.faqs[index].question ?? '',
        style: TextStyle(
          color: Colors.black,
          fontSize: 15,
          fontWeight: FontWeight.w600,
        ),
      ),
      children: <Widget>[
        ListTile(
          title: Container(
            decoration: BoxDecoration(
              color: Colors.grey.withOpacity(0.1),
              borderRadius: const BorderRadius.all(Radius.circular(5.0)),
            ),
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Text(
                courseFaqController.faqs[index].answer ?? '',
                style: TextStyle(fontSize: 14, fontWeight: FontWeight.w400),
              ),
            ),
          ),
        ),
      ],
    ),

    5. Controller Implementation

    The CourseFaqController manages the API call and stores the FAQ data. It uses GetX’s reactive state management to update the UI when data changes.

    Note: Create your own controller

    import 'package:get/get.dart';
    import 'package:solh/constants/api.dart';
    
    class CourseFaqController extends GetxController {
      var isLoading = false.obs;
      var err = ''.obs;
      var faqs = <Faqs>[].obs;
    
      Future<void> getCourseFaq(String id) async {
        try {
          isLoading.value = true;
          final response = await GetConnect().get("${APIConstants.api}/api/lms/user/course-faqs/$id");
          if (response.status.hasError) {
            err.value = response.statusText ?? "Unknown error";
          } else {
            faqs.value = List<Faqs>.from(response.body['faqs'].map((x) => Faqs.fromJson(x)));
          }
        } catch (e) {
          err.value = e.toString();
        } finally {
          isLoading.value = false;
        }
      }
    }

    Output

    Complete code

    
    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    import 'package:solh/constants/api.dart';
    
    class CourseFaqScreen extends StatefulWidget {
      final Map<String, dynamic> args;
      const CourseFaqScreen({Key? key, required this.args}) : super(key: key);
    
      @override
      _CourseFaqScreenState createState() => _CourseFaqScreenState();
    }
    
    class _CourseFaqScreenState extends State<CourseFaqScreen> {
      final CourseFaqController courseFaqController = Get.find();
    
      @override
      void initState() {
        super.initState();
        courseFaqController.getCourseFaq(widget.args['courseId']);
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text("FAQs"),
            backgroundColor: Colors.blueAccent,
          ),
          body: Container(
            height: double.infinity,
            decoration: const BoxDecoration(
              gradient: LinearGradient(
                colors: [
                  Colors.blueAccent,
                  Colors.lightBlue,
                ],
                begin: Alignment.topCenter,
                end: Alignment.bottomCenter,
              ),
            ),
            child: Obx(() {
              if (courseFaqController.isLoading.value) {
                return const Center(child: CircularProgressIndicator());
              }
              if (courseFaqController.faqs.isEmpty) {
                return const Center(child: Text("No FAQs Available"));
              }
              return ListView.builder(
                itemCount: courseFaqController.faqs.length,
                itemBuilder: (context, index) {
                  return ExpansionTile(
                    title: Text(
                      courseFaqController.faqs[index].question ?? '',
                      style: const TextStyle(
                        color: Colors.black,
                        fontSize: 15,
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                    children: <Widget>[
                      ListTile(
                        title: Container(
                          decoration: BoxDecoration(
                            color: Colors.grey.withOpacity(0.1),
                            borderRadius: const BorderRadius.all(Radius.circular(5.0)),
                          ),
                          child: Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: Text(
                              courseFaqController.faqs[index].answer ?? '',
                              style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w400),
                            ),
                          ),
                        ),
                      ),
                    ],
                  );
                },
              );
            }),
          ),
        );
      }
    }
    
    class CourseFaqController extends GetxController {
      var isLoading = false.obs;
      var err = ''.obs;
      var faqs = <Faqs>[].obs;
    
      Future<void> getCourseFaq(String id) async {
        try {
          isLoading.value = true;
          final response = await GetConnect().get("${APIConstants.api}/api/lms/user/course-faqs/$id");
          if (response.status.hasError) {
            err.value = response.statusText ?? "Unknown error";
          } else {
            faqs.value = List<Faqs>.from(response.body['faqs'].map((x) => Faqs.fromJson(x)));
          }
        } catch (e) {
          err.value = e.toString();
        } finally {
          isLoading.value = false;
        }
      }
    }
    
    class Faqs {
      final String? question;
      final String? answer;
    
      Faqs({this.question, this.answer});
    
      factory Faqs.fromJson(Map<String, dynamic> json) {
        return Faqs(
          question: json['question'],
          answer: json['answer'],
        );
      }
    }
    

    Why Use ExpansionTile for FAQs?

    • Provides a clean and organized way to display questions and answers.
    • Saves screen space by keeping answers hidden until tapped.
    • Smooth expand/collapse animations improve user experience.

    Conclusion

    This implementation provides a scalable way to handle FAQs in Flutter applications. By leveraging ExpansionTile and ListView.builder, we ensure the list is dynamically generated and updates automatically when new data is fetched. The use of Obx makes state management seamless, making this approach ideal for apps that require real-time FAQ updates.

    Related Articles

    • Related Articles
    • How to make Ludo app in Flutter with Source Code Step by step
    • How to make PDF Reader app in Flutter with Source Code Step by step
    • How to make QR Scanner app in Flutter with Source Code Step by step
    • How to Make a ToDo App with Flutter with source Code StepWise in 2024
    • What is package in Flutter (Dart) with example in 2024
    • What is class in Flutter(Dart) with example step by step
    • Advantage of Flutter with examples in 2024
    • Top 15 Amazing Applications Built with Flutter Framework
    • Creating an Instruction UI Screen in Flutter Application

    Share. Facebook Twitter LinkedIn WhatsApp Telegram Pinterest Reddit Email
    Previous ArticleCreating an Instruction UI Screen in Flutter Application

    Related Posts

    Creating an Instruction UI Screen in Flutter Application

    FLUTTER UI 7 Mins Read

    Animated Backgrounds in Flutter: A Complete Guide

    FLUTTER 4 Mins Read

    How to make ListView Builder Ui in flutter with Source Code

    FLUTTER UI 5 Mins Read

    Create a TabBar View in flutter with fully functional stepwise

    FLUTTER UI 6 Mins Read

    Leave A Reply Cancel Reply

    Recent Posts
    • Implementing a Dynamic FAQ Screen UI in Flutter Using ExpansionTile March 29, 2025
    • Creating an Instruction UI Screen in Flutter Application March 29, 2025
    • Animated Backgrounds in Flutter: A Complete Guide March 15, 2025
    • How to make Diary App using flutter stepwise using getx August 31, 2024
    • How to Create Music Player UI screen with fully functional in flutter August 30, 2024
    • How to make ListView Builder Ui in flutter with Source Code August 29, 2024
    • Create a TabBar View in flutter with fully functional stepwise August 28, 2024
    • How to create TabBar view in flutter with source code step wise August 27, 2024
    • How to make Heart rate measure app with Flutter stepwise August 26, 2024
    • How to make ChatGpt App in flutter with source code Stepwise August 25, 2024
    Facebook Twitter Instagram Pinterest YouTube
    • About
    • Contact
    • Disclaimer
    • Privacy Policy
    Copyright by DeepCrazyWorld © 2025

    Type above and press Enter to search. Press Esc to cancel.