Open In App

Flutter – Create Fortune Wheel Spin

Last Updated : 06 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Deciding what to eat can be a daily dilemma, especially when you have a plethora of options to choose from. To make this decision-making process more exciting and interactive, in this article, we will be creating – the Lunch Spinning Wheel app. A sample video is given below to get an idea about what we are going to do in this article.

Prerequisites

Before we dive into the implementation, make sure Flutter is installed on the system or download it from the official Flutter website. Also, ensure that a code editor is installed, such as Visual Studio Code or Android Studio.

Step-by-Step Implementation

Step 1: Create Project

In the Visual Studio Code terminal run the below command to create a Flutter project:

Dart




flutter create lunch_spinning_wheel


Step 2: Add libraries

Now we need to add the package into the pubspec.yaml file. From the command line:

Dart




flutter pub add flutter_fortune_wheel http confetti


This will add all packages under dependencies section in pubspec.yaml file as shown below:

yaml2

Step 3: Import libraries

Now, import these packages in main.dart file,

Dart




import 'package:http/http.dart' as http;
import 'package:flutter_fortune_wheel/flutter_fortune_wheel.dart';
import 'package:confetti/confetti.dart';


Step 4: Create Lunch Class

Create Lunch class that requires the meal parameter to be provided when creating an instance of the Lunch class and the img parameter is optional. The fromJson factory method is used to create Lunch instances by extracting values from a JSON map.

Dart




class Lunch {
  final String meal;
  var img;
  
  Lunch({required this.meal, this.img});
  
  factory Lunch.fromJson(Map<String, dynamic> json) {
    return Lunch(meal: json['strMeal'], img: json['strMealThumb']);
  }
}


Step 5: Loading Lunch Ideas from an API

Fetch a list of lunch ideas from the MealDB API to retrieve a variety of Indian meal options.

Dart




 List<Lunch> _ideas = [];
 
 Future<void> _getLunchIdeas() async {
   http.Response response;
 
   Uri uri = Uri.parse(url);
   response = await http.get(uri);
 
   if (response.statusCode == 200) {
     Map<String, dynamic> jsonData = json.decode(response.body);
 
     if (jsonData['meals'] != null) {
       List<dynamic> meals = jsonData['meals'];
       setState(() {
         _ideas = meals.map((json) => Lunch.fromJson(json)).toList();
       });
     }
   }
 }


Step 6: Create the Spinning Wheel

The spinning wheel is implemented using the FortuneWheel widget provided by the Flutter Fortune Wheel package. It takes the list of lunch ideas and randomly selects one when the wheel is spun. The selected idea is displayed in alert dialog when wheel is stopped.

Dart




FortuneWheel(
             selected: selected.stream,
             items: [
                    for (var it in _ideas)
                              FortuneItem(child: Text(it.meal)),
                          ],
                          onAnimationEnd: () {
                            _centerController.play();
                            showDialog(
                                barrierDismissible: true,
                                context: context,
                                builder: (BuildContext context) {
                                  return Center(
                                    child: AlertDialog(
                                      scrollable: true,
                                      title: Text("Hurray! today's meal is????"),
                                      content: Column(
                                        children: [
                                          ConfettiWidget(
                                              confettiController:
                                                  _centerController,
                                              blastDirection: pi / 2,
                                              maxBlastForce: 5,
                                              minBlastForce: 1,
                                              emissionFrequency: 0.03,
                                              numberOfParticles: 10,
                                              gravity: 0),
                                          SizedBox(height: 10),
                                          Text(
                                            selectedIdea,
                                            style: TextStyle(fontSize: 22),
                                          ),
                                          SizedBox(height: 20),
                                          Image.network(selectedImg),
                                        ],
                                      ),
                                    ),
                                  );
                                });
                          },
                          onFocusItemChanged: (value) {
                            if (flag == true) {
                              setValue(value);
                            } else {
                              flag = true;
                            }
                          },
                        ),


Complete Code

Dart




import 'dart:async';
import 'dart:convert';
import 'dart:math';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:flutter_fortune_wheel/flutter_fortune_wheel.dart';
import 'package:confetti/confetti.dart';
  
void main() => runApp(const MyApp());
  
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Gfg Lunch Wheel',
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: ExamplePage(),
    );
  }
}
  
class ExamplePage extends StatefulWidget {
  @override
  _ExamplePageState createState() => _ExamplePageState();
}
  
class Lunch {
  final String meal;
  var img;
  
  Lunch({required this.meal, this.img});
  
  factory Lunch.fromJson(Map<String, dynamic> json) {
    return Lunch(meal: json['strMeal'], img: json['strMealThumb']);
  }
}
  
class _ExamplePageState extends State<ExamplePage> {
  StreamController<int> selected = StreamController<int>();
  late ConfettiController _centerController;
  
  List<Lunch> _ideas = [];
  
  Future<void> _getLunchIdeas() async {
    http.Response response;
  
    Uri uri = Uri.parse(url);
    response = await http.get(uri);
  
    if (response.statusCode == 200) {
      Map<String, dynamic> jsonData = json.decode(response.body);
  
      if (jsonData['meals'] != null) {
        List<dynamic> meals = jsonData['meals'];
        setState(() {
          _ideas = meals.map((json) => Lunch.fromJson(json)).toList();
        });
      }
    }
  }
  
  @override
  void initState() {
    super.initState();
    _getLunchIdeas();
    _centerController =
        ConfettiController(duration: const Duration(seconds: 10));
  }
  
  @override
  void dispose() {
    selected.close();
    _centerController.dispose();
    super.dispose();
  }
  
  var selectedIdea = "";
  late var selectedImg;
  void setValue(value) {
    selectedIdea = _ideas[value].meal.toString();
    selectedImg = _ideas[value].img;
  }
  
  @override
  Widget build(BuildContext context) {
    var flag = false;
  
    return Scaffold(
        appBar: AppBar(
          centerTitle: true,
          title: const Text('Gfg Lunch Wheel'),
        ),
        body: _ideas.length > 2
            ? Padding(
                padding: const EdgeInsets.all(8.0),
                child: GestureDetector(
                  onTap: () {
                    setState(() {
                      selected.add(
                        Fortune.randomInt(0, _ideas.length),
                      );
                    });
                  },
                  child: Column(
                    children: [
                      Expanded(
                        child: FortuneWheel(
                          selected: selected.stream,
                          items: [
                            for (var it in _ideas)
                              FortuneItem(child: Text(it.meal)),
                          ],
                          onAnimationEnd: () {
                            _centerController.play();
                            showDialog(
                                barrierDismissible: true,
                                context: context,
                                builder: (BuildContext context) {
                                  return Center(
                                    child: AlertDialog(
                                      scrollable: true,
                                      title: Text("Hurray! today's meal is????"),
                                      content: Column(
                                        children: [
                                          ConfettiWidget(
                                              confettiController:
                                                  _centerController,
                                              blastDirection: pi / 2,
                                              maxBlastForce: 5,
                                              minBlastForce: 1,
                                              emissionFrequency: 0.03,
                                              numberOfParticles: 10,
                                              gravity: 0),
                                          SizedBox(height: 10),
                                          Text(
                                            selectedIdea,
                                            style: TextStyle(fontSize: 22),
                                          ),
                                          SizedBox(height: 20),
                                          Image.network(selectedImg),
                                        ],
                                      ),
                                    ),
                                  );
                                });
                          },
                          onFocusItemChanged: (value) {
                            if (flag == true) {
                              setValue(value);
                            } else {
                              flag = true;
                            }
                          },
                        ),
                      ),
                    ],
                  ),
                ),
              )
            : Center(
                child: CircularProgressIndicator(color: Colors.green),
              ));
  }
}


Output:



Similar Reads

Flutter - Spin Bottle Animation
In Flutter, Spin Bottle Animation is a fun and attractive animation, here we can achieve this by using the Flutter RotationTransition and AnimatedBuilder widget, In this animation, a bottle is rotated when we press a button. In this article, we are going to implement the Spin Bottle Animation using RotationTransition and AnimatedBuilder widget. A s
5 min read
Create a Spin the Bottle game using React-Native
React-Native is an open-source framework used to develop cross-platform applications i.e., you can write code in React-Native and publish it as an Android or IOS app. In this article, we will build a basic Spin the Bottle game in React-Native. This is a multi-player game. Usually, people sit in a round with a bottle at the center. When the bottle s
3 min read
Is Flutter Worth Learning? Top 7 Reasons to Learn Flutter
In today's era, the usage of smartphones has increased exponentially and so has the use of mobile applications and websites. Meanwhile, considering future career prospects, learning web development and mobile app development is strongly recommended for all individuals. And when we come to mobile app development, there are two most-popular open-sour
5 min read
Flutter - Sharing Data Among Flutter Pages
In this article, we are going to find the solution for the problem statement "Import/send data from one page to another in flutter". Before going into the topic, there are some pre-requisites. Pre-requisites:Basics of dart programming language.Setting up Flutter in VS code or Setting up Flutter in Android Studio.Creating first flutter app | Hello W
4 min read
Flutter Quill - Rich Text Editor in Flutter Application
This post will explain how to integrate a rich text editor into your Flutter application so that it may enable rich text editing. There are many more things we can do with Flutter Quill, but they can get a little involved. The example below is a pretty basic demonstration of what we mean. Let's first discuss what flutter quill is and why we need it
5 min read
Flutter - Animated AlertDialog in Flutter
Animating an AlertDialog in Flutter involves using the Flutter animations framework to create custom animations for showing and hiding the dialogue. In this article, we are going to add an animation to an AlertDialog. A sample video is given below to get an idea about what we are going to do in this article. [video mp4="https://media.geeksforgeeks.
4 min read
Flutter - Different Types of Loading using Flutter EasyLoading
Flutter applications involve incorporating loading indicators to provide users with feedback during background operations. Flutter has a package for simplifying the process named flutter_easyloading package. This package easiest way to integrate loading indicators with various styles. In this article, we will implement different types of loading in
5 min read
How to Create a Zoomable Image in Flutter?
In Flutter, you can create a zoomable image using the GestureDetector and Transform widgets. The GestureDetector widget can be used to detect pinch gestures on the image, and the Transform widget can be used to apply the zoom transformation to the image. [video mp4="https://media.geeksforgeeks.org/wp-content/uploads/20230117115430/zoomableimage-202
3 min read
How to Create Buttons with Rounded Corners in Flutter?
Flutter is a UI toolkit developed by Google. It is being utilized by big tech companies like Alibaba, Airbnb, and Google itself to build apps that serve billions of users around the globe. In this article, we will be seeing how to make Rounded Buttons in Flutter. Approach: We will create the buttons and use their style property to give them a borde
2 min read
How to Create a Desktop Window Application in Flutter?
The flutter team recently release Flutter version 2.10 with Desktop support. Desktop support allows you to compile Flutter source code to a native Windows, macOS, or Linux desktop app. Flutter’s desktop support also extends to plugins—you can install existing plugins that support the Windows, macOS, or Linux platforms, or you can create your own. R
3 min read