Top Flutter Interview questions that should be helpful

In the current year, as a mid-level Flutter Engineer, I tried to appear in several physical and remote interviews and got to know about a variety of other concepts apart from my limited knowledge, and on behalf of that I tried to enhance my knowledge further. However, in this blog post, let’s prepare ourselves for the top Flutter Interview questions.

Note: This blog post will cover questions/answers ranging from a just-started-guy to a professional Developer. Here’s a list of questions that I have managed to jot down for my audience.

Table of Contents


Questions & Answers

Q1- Object-Oriented Programming pillars?

1- Abstraction

Hiding the irrelevant information to reduce code complexity and increase efficiency.

Here’s how we can implement abstraction:

abstract class Quotes {
  Future<Quote> getQuotes();
}

class MotivationalQuotes extends Quotes {
  @override
  Future<Quote> getQuotes() async {
     ///some code
  }
}

2- Inheritance

There is no need to shed light on this one, I guess, as Dart is an Object-Oriented Language and always fulfills the concept of inheritance, i.e. extends keyword.

3- Polymorphism

In Polymorphism, an object can take on multiple forms and respond in different ways based on the context it is used in.

In Dart, we can implement this approach in several ways:

By inheritance

A subclass inherits properties from its superclass.

By interface

Dart supports Interface, although it doesn’t have an interface keyword.

Furthermore, we use the implements keyword with the actual properties and methods that a class must possess, such as mixins, etc.

Here’s how we can implement Polymorphism:

class Animal {
  void makeSound() {
    print('Generic animal sound');
  }
}

class Dog extends Animal {
  void makeSound() {
    print('Bark!');
  }
}

class Cat extends Animal {
  void makeSound() {
    print('Meow!');
  }
}

void main() {
  Animal animal = new Animal();
  Animal dog = new Dog();
  Animal cat = new Cat();

  animal.makeSound(); // Output: Generic animal sound
  dog.makeSound(); // Output: Bark!
  cat.makeSound(); // Output: Meow!
}

4- Encapsulation

In Encapsulation, a class must contain all of its methods and declared variables under the access modifier - private to prevent any unauthorized access while providing a public interface through which an object can interact with it.

Here’s how we can implement Encapsulation:

class Person {
  String? _name;
  int? _age;
  
  String get name => _name!;
  set name(String value) => _name = value;
  
  int get age => _age!;
  set age(int value) => _age = value;
  
  void speak() {
    print('Hello, my name is $_name, and I am $_age years old.');
  }
}

void main() {
  var person = Person();
  person.name = 'John';
  person.age = 30;
  person.speak(); // Output: Hello, my name is John, and I am 30 years old.
}

Q2- Difference b/w Listview and Listview builders?

– ListView

A ListView renders objects that are visible on the screen. Let’s look into this via a code snippet:

class MyApp1 extends StatelessWidget {
  const MyApp1({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: SafeArea(
        child: ListView(
          padding: const EdgeInsets.symmetric(horizontal: 2, vertical: 2),
          keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
          children: [
            card,
            card,
            card,
            card,
            card,
            card,
          ],
        ),
      ),
    );
  }


  Widget get card => Card(
        clipBehavior: Clip.hardEdge,
        borderOnForeground: true,
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 12),
          child: Row(
            children: [
              Column(
                children: const [
                  Text(
                    "Flutter Test",
                    style: TextStyle(fontSize: 20, fontWeight: FontWeight.w700),
                  ),
                  Text(
                    "Some description",
                    style: TextStyle(fontSize: 14, fontWeight: FontWeight.w700),
                  ),
                ],
              ),
              const Spacer(),
              Column(
                children: [
                  const FlutterLogo(),
                  const SizedBox(
                    height: 10,
                  ),
                  ElevatedButton(onPressed: () {}, child: const Text("Click"))
                ],
              ),
            ],
          ),
        ),
      );
}

Furthermore, in the above class, a custom Card widget is rendered under a ListView six times. Upon running we get,

Top Flutter Interview questions - listview example

ListView.builder / ListView.separator

Both of the above only render those widgets that are visible to the user on the screen.

You might think that you provided the same definition for both. So what’s the difference? Well, on considering ListView, if the card widget had a count of 50 or above, the ListView would have made the frame go high and the chances of the app crashing. Here comes ListView.builder/separator to the rescue, since it renders the other items on scroll only.

Here’s the updated version of it:

class MyApp1 extends StatelessWidget {
  const MyApp1({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: SafeArea(
        child: ListView.separator(
          padding: const EdgeInsets.symmetric(horizontal: 2, vertical: 2),
          shrinkWrap: true,
          itemCount: 62,
          itemBuilder: (context, i) => card,
          separatorBuilder: (context, _) => SizedBox(height: 10),
        ),
      ),
    );
  }


  Widget get card => CardWidget(),
}

Q3- Single and Multi threads in Dart?

Q4- What are Isolates?

I shall answer Q3-4 in a merged format since it’s relatable. Dart is a single-threaded language, which means it runs on a single isolate, to even perform some heavy operations, whereas, multi-threading means that several processors can make use of a single code base to run them at various execution stages.

Apart from this, we can also run some other computations on other isolates by communicating through different ports.

Q5- What is Asynchronous programming?

It allows other operations to finish once they get executed.

Here’s a detailed tutorial available. Check it out:

Q6- Stream and its types with practical examples?

Streams are a way of handling asynchronous data, a continuous flow of data, by listening to events in real-time and responding to them.

Dart supports two types of Streams:

Single Subscription Streams

Consider this code snippet:

  final StreamController<int> _streamController = StreamController();
  StreamSubscription<int>? _streamSubscription;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    _streamSubscription = _streamController.stream.listen((value) {
      debugPrint("Listening value $value");
    });
  }

   ElevatedButton(
       onPressed: () {
         _streamController.sink.add(22);
         _streamController.sink.add(44);
         _streamController.sink.add(66);
      },
      child: const Text("Click"),
)

Each time we press the button, we will see three values printed on the console.

Single stream output

Additionally, upon unsubscribing from the stream,

ElevatedButton(
       onPressed: () {
         _streamSubscription!.cancel();  /// unsubscibe
         _streamController.sink.add(22);
         _streamController.sink.add(44);
         _streamController.sink.add(66);
      },
      child: const Text("Click"),
)

Broadcast streams

Consider the following code snippet:

final StreamController<bool> _streamController = StreamController();

StreamBuilder<bool>(
              stream: _streamController.stream,
              initialData: true,
              builder: (context, s) => TextFormField(
                obscureText: s.data!,
                decoration: InputDecoration(
                  suffixIcon: InkWell(
                    child: Icon(s.data!
                        ? Icons.visibility_off
                        : Icons.visibility),
                    onTap: () {
                      if (s.data!) {
                        _streamController.sink.add(false);
                      } else {
                        _streamController.sink.add(true);
                      }
                    },
                  ),
                  hintText: 'Password',
                ),
              ),
            ),

A stream controller has been attached to a TextFormField and can toggle passwords to obscure text.

What if we duplicate this one (both attached to the same controller)?

We see the error: Bad State, the stream has already been listened to.

Here comes the use of the Broadcast stream.

We need to take the following into account:

  • Create a new stream of the same type
  • Assign the existing stream controller as a broadcast
  • Attach the Stream with FormFields

Here’s the code snapshot:

final StreamController<bool> _streamController = StreamController();
  Stream<bool>? _stream;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    _stream = Stream.value(true);
    _stream = _streamController.stream.asBroadcastStream(); /// *imp*
  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<bool>(
      stream: _streamController.stream,
      initialData: true,
      builder: (context, s) => TextFormField(
          obscureText: s.data!,
          decoration: InputDecoration(
          suffixIcon: InkWell(
          child: Icon(s.data!
                  ? Icons.visibility_off
                  : Icons.visibility),
              onTap: () {
                 if (s.data!) {
                    _streamController.sink.add(false);
                   } else {
                    _streamController.sink.add(true);
                  }
                },
              ),
         hintText: 'Password',
       ),
     ),
   ) x 2
}

Q7- What is the use of Tickers in Flutter?

Flutter uses Tickers to refresh the frame rate.

Mainly used for Animations, as Flutter is quite impressive in its UI module, the re-rendering of the frame looks natural.

However, this callback only works when the widget is visible.

We use SingleTickerProviderStateMixin to apply Tickers.

Here’s a simple snippet:

import 'package:flutter/material.dart';

class CustomAnimationWidget extends StatefulWidget {
  const CustomAnimationWidget({Key? key, required this.child}) : super(key: key);

  final Widget child;

  @override
  State<CustomAnimationWidget> createState() => _CustomAnimationWidgetState();
}

class _CustomAnimationWidgetState extends State<CustomAnimationWidget> with SingleTickerProviderStateMixin {

  AnimationController? animationController;
  Animation<double>? animation;

  @override
  void initState() {
    // TODO: implement initState
    animationController = AnimationController(vsync: this, duration: Duration(milliseconds: 500))..forward();

    animation = CurvedAnimation(parent: animationController!, curve: Curves.slowMiddle);
    super.initState();
  }

  @override
  void dispose() {
    // TODO: implement dispose
    animationController!.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return FadeTransition(
      sizeFactor: animationController!,
      child: widget.child,
    );
  }
}

Q8- Explain the Factory keyword.

A Factory keyword prevents a class from creating a new instance of itself. Secondly, there are two points to remember when making use of this keyword.

  • The return statement is used in the same instance.
  • Factory doesn’t support this keyword.

Q9- Why do we need Singleton classes in Flutter?

Singletons are a great concept that lets our class declare only instances of it, also allowing global access.

Furthermore, it is much less talked about and less highlighted, yet a great relief for developers out there.

Consider this class snippet:

class DummyQuotes {
  static final DummyQuotes quotes = DummyQuotes._();
  DummyQuotes._();
  
  void testMethod() => debugPrint("Just a test...");
}

Q10- Difference b/w Stateless and Stateful Widgets?

Here’s a detailed tutorial available. Check it out:

Q11- How can we pass arguments from child to parent class?

Let’s understand this via code snippets:

class DemoApp extends StatefulWidget {
  const DemoApp({Key? key}) : super(key: key);

  @override
  State<DemoApp> createState() => _DemoAppState();
}

class _DemoAppState extends State<DemoApp> {

  String _text = "Parent Widget String";

  updateValue(val) => setState(() {
    _text = val;
  });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Pass Data from Child to Parent"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              _text,
              style: const TextStyle(fontSize: 22, fontWeight: FontWeight.w800),
            ),

            CustomChildWidget(callBack: updateValue),
          ],
        ),
      ),
    );
  }
}


// Child class
class CustomChildWidget extends StatelessWidget {
  const CustomChildWidget({Key? key, required this.callBack}) : super(key: key);

  final ValueChanged<String> callBack;

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () => callBack("Updated String"),
      child: const Text("Updated"),
    );
  }
}

In the above snippet, I have created a Stateful Widget class that has:

  • A string
  • A string function with one argument

In addition, we have a custom child widget that has an Elevated Button and requires a callback of string type.

Upon running this code, we get:

Q12- Explain the Fluter StatefulWidget Lifecycle.

Here’s a great in-depth article about the Stateful Widget lifecycle. Check it out:

Q13- Difference b/w a package and a plugin?

A package contains only Dart code, whereas a plugin has both Dart and Native code.

One thing interesting here is that:

A package may use plugins if needed. It will still qualify as a package.

Q14- Your preferred State Management and why?

This question would surely be asked in the interview.

It depends on the developer himself. Nowadays, many prefer Bloc to Provider or GetX, so choose the one that suits you best.

Q15- Your preferred Architectural Pattern?

This question represents the same answer as above. What’s your choice:

MVVM

MVC

Clean Architecture

It’s time to wrap up this article.

Note: I shall modify this blog post with more questions in the future.


Wrapping Up

Thanks for your precious time.

Hope you enjoyed every bit of it.

So, in this blog, we learned about Top Flutter Interview questions with detailed and short answers, viewed some code snippets and examples, etc.

If you have any sort of questions available, please share them with me in the comments section below. I would love to know that as well.

Link to GitHub Repositories, and YouTube Channel

Read out previous blogs – Click here

Also, read Flutter’s Stateful Widget LifeCycle

6 thoughts on “Top Flutter Interview questions that should be helpful”

  1. I’m very happy to discover this website. I need to to thank you for ones time for this wonderful read!!
    I definitely liked every little bit of it and i also have you book marked to see new stuff on your site.

    Reply
  2. It’s really a great and helpful piece of information.
    I’m glad that you just shared this useful info with us.
    Please keep us up to date like this. Thank you for sharing.

    Reply

Leave a Comment