YouTip LogoYouTip

Flutter Advanced

Flutter Advanced |

This section introduces some advanced Flutter concepts to help enhance your development skills.


Rendering Principles

Flutter uses the Skia (gradually switching to Impeller since 3.0) rendering engine to directly draw UI, without relying on native components.

Widget Tree, Element Tree, and RenderObject Tree

  • Widget Tree: Describes UI configuration (immutable)
  • Element Tree: Instantiated objects of Widgets (mutable)
  • RenderObject Tree: Responsible for actual rendering
Understanding rendering principles helps optimize UI performance and avoid unnecessary rebuilds.

InheritedWidget β€” Data Passing

InheritedWidget allows data to be passed down the Widget tree, enabling child widgets to access data from their ancestors.

Example: Custom InheritedWidget

// Define data container

class MyData extends InheritedWidget {

final int value;

const MyData({

super.key,

 required this.value,

 required super.child,

});

// Convenience method: get the nearest MyData

static MyData of(BuildContext context){

return context.dependOnInheritedWidgetOfExactType()!;

}

// Determine whether child widgets need to be rebuilt

 @override

bool updateShouldNotify(MyData oldWidget){

return value != oldWidget.value;

}

}

// Usage

class ParentWidget extends StatelessWidget {

const ParentWidget({super.key});

@override

 Widget build(BuildContext context){

return MyData(

 value:42,

 child:const ChildWidget(),

);

}

}

class ChildWidget extends StatelessWidget {

const ChildWidget({super.key});

@override

 Widget build(BuildContext context){

// Get ancestor MyData

final myData = MyData.of(context);

return Text('Value: ${myData.value}');

}

}

RepaintBoundary β€” Local Repainting

Using RepaintBoundary restricts the repaint area, improving performance.

Example: Using RepaintBoundary

class MyWidget extends StatelessWidget {

const MyWidget({super.key});

@override

 Widget build(BuildContext context){

return RepaintBoundary(

 child: Container(

// Drawing in this area won’t affect the outside

 color: Colors.red,

 child:const Text('Independent Area'),

),

);

}

}

Deep Understanding of Keys

Keys help Flutter identify Widgets and distinguish between new and existing Widgets.

ValueKey vs ObjectKey vs UniqueKey

Type Description
ValueKey Uses a value as the key (e.g., ID, number, string)
ObjectKey Uses an object reference as the key
UniqueKey Generates a unique key each time it’s created, preventing rebuild reuse

CustomPainter β€” Custom Drawing

CustomPainter enables fully custom graphics rendering.

Example: Using CustomPainter

class CustomPainterExample extends StatelessWidget {

const CustomPainterExample({super.key});

@override

 Widget build(BuildContext context){

return CustomPaint(

 painter: MyCirclePainter(),

 size:const Size(200,200),

);

}

}

class MyCirclePainter extends CustomPainter {

 @override

void paint(Canvas canvas, Size size){

// Draw circle

final paint = Paint()

..color= Colors.blue

..style= PaintingStyle.fill;

final center = Offset(size.width/2, size.height/2);

final radius = size.width/2-10;

canvas.drawCircle(center, radius, paint);

// Draw border

final borderPaint = Paint()

..color= Colors.black

..style= PaintingStyle.stroke

..strokeWidth=2;

canvas.drawCircle(center, radius, borderPaint);

}

@override

bool shouldRepaint(covariant CustomPainter oldDelegate){

return false;

}

}

Stream and Future

Example: Using Stream

// Create Stream

 Stream<int> countStream(int max) async*{

for(int i =1; i <= max; i++){

 await Future.delayed(const Duration(seconds:1));

 yield i;// Emit value

}

}

// Use StreamBuilder

class StreamExample extends StatelessWidget {

const StreamExample({super.key});

@override

 Widget build(BuildContext context){

return StreamBuilder<int>(

 stream: countStream(10),

 builder:(context, snapshot){

if(snapshot.hasData){

return Text('Count: ${snapshot.data}');

}else if(snapshot.hasError){

return Text('Error: ${snapshot.error}');

}

return const CircularProgressIndicator();

},

);

}

}

Summary

This Flutter tutorial covers the following topics:

  • Flutter installation and environment setup
  • Widget fundamentals (StatelessWidget and StatefulWidget)
  • Layout system (Row, Column, Stack)
  • Handling user input
  • State management (setState, Provider)
  • Network requests and data storage
  • Navigation and routing
  • Testing and publishing

For further learning, consider exploring:

  • BLoC pattern
  • Riverpod state management
  • GetX routing and state management
  • Flutter performance optimization
  • Flutter Web and desktop development
← Codex AppFlutter Best Practices β†’