As a Flutter developer, it's very common to refactor widgets into new files. The extension allows you to extract a selection of code into a stateless widget class, handling the import and file creation. This allows for smooth extraction without the need for a mouse.
Here is a simple Widget extraction when press "CMD/CTRL+ALT+E":
Here is another Widget extraction with properties specified:
- Open the Dart file you wish to modify within your Flutter project.
- Choose the Widget you intend to transform into a new StatelessWidget.
- Right-click on the selected text and opt for "Extract Flutter Widget to File," or use the shortcut "Cmd+Alt+E."
- In the prompt that appears, provide a path relative to "lib," such as "components/tiles/MyWidget." The "MyWidget" will be camelcased, and the extension will generate a directory at "lib/components/tiles" along with a file named "my_widget.dart" within it.
- Optionally, you may specify properties after the ";" to create fields within the newly created file.
- Within the current file, the statement "import $packageName/components/tiles/my_widget.dart" will be appended to the import statements.
- The selected widget will be replaced with "MyWidget()" along with its specified properties.
Below is an example of how to use the extension by selecting a Container Widget and converting it into a new StatelessWidget class named "MyNewWidget":
main.dart (before)
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('My App')),
body: ListView.builder(
itemBuilder: (context, index) {
final song = songs[index];
return ListTile(
title: Text(song.name),
subtitle: Text(song.artistName),
leading: CircleAvatar(
backgroundImage: AssetImage(song.coverPath),
),
trailing: Icon(Icons.delete),
onTap: () => goToSongPage(index),
);
},
itemCount: songs.length,
),
),
);
}
}
press Cmd+Atl+E
, in the prompt box, typing: components/tiles/MyTile;Song song,void Function()? onTap
, will generate:
main.dart (after)
import 'package:flutter/material.dart';
import "package:hello_world_app/components/tiles/my_tile.dart"; //this will automatically inserted
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('My App')),
body: ListView.builder(
itemBuilder: (context, index) {
final song = songs[index];
return MyTile(
song: null, //Here just assgin variable
onTap: null, //Here assign the handler
);
},
itemCount: songs.length,
),
),
);
}
}
lib/components/tiles/my_tile.dart
import 'package:flutter/material.dart';
import 'package:hello_world_app/models/song.dart';
class MyTile extends StatelessWidget {
final Song song;
final void Function()? onTap;
const MyTile({super.key, required this.song, required this.onTap});
@override
Widget build(BuildContext context) {
return ListTile(
title: Text(song.name),
subtitle: Text(song.artistName),
leading: CircleAvatar(
backgroundImage: AssetImage(song.coverPath),
),
trailing: Icon(Icons.delete),
onTap: onTap,
);
}
}
Inspired by Flutter Extract Widget and Create Part and VSCode Advanced New File.