22

I did the following test, but it doesn't work:

//main.dart
class Test
{
  static const   a = 10;
  final b = 20;
  final c = a+1;

}

//part.dart
part of 'main.dart';
class Test
{
  final d = a +1;   //<---undefined name 'a'
} 

I would like to split the class in flutter tutorial into multiple files. For example: _buildSuggestions in a separate file, _buildRow in a separate file, etc.

update:

my solution:

before:

//main.dart
class RandomWordsState extends State<RandomWords> {
{
    final _var1;
    final _var2;
    @override
    Widget build(BuildContext context) {
      ...
      body: _buildList(),
    );

    Widget _buildList() { ... }
    Widget _buildRow() { ... }
}

after:

//main.dart
import 'buildlist.dart';
class RandomWordsState extends State<RandomWords> {
{
    final var1;
    final var2;
    @override
    Widget build(BuildContext context) {
      ...
      body: buildList(this),
    );

}

//buildlist.dart
import 'main.dart';

  Widget buildList(RandomWordsState obj) {
     ... obj.var1 ...
  }
1
  • 1
    You can just import other files if accesss to private members isn't an issue. Which part isn't answered by my answer or which part of what you want to accomplish does cause you troubles? Commented Apr 1, 2018 at 15:13

4 Answers 4

27

I am faced with same problem. My variant based on extensions:

page.dart

part 'section.dart';

class _PageState extends State<Page> {
    build(BuildContext context) {
        // ...
        _buildSection(context);
        // ...
    }
}

section.dart

part of 'page.dart';

extension Section on _PageState {
    _buildSection(BuildContext context) {
        // ...
    }
}
5
  • Wow, this looks like a cool way to use partial files (like C# visual Studio). Do you know if there is some information pro or against this practice? Commented May 24, 2021 at 21:16
  • 2
    @adrianvintu iOS developers use in this way on swift. After compilation this is the same as one big class. Commented May 27, 2021 at 15:43
  • 1
    As a Swift dev, this is exactly what I was looking for! The only new thing is having to declare the part inside the main class file and its associated part of in your extension. Thanks! Commented Jul 16, 2022 at 22:45
  • 1
    Great solution! You will have to remove all other directives from section.dart, e.g. import directives, in case there are, as it was the case with my code. Commented Aug 22, 2023 at 20:48
  • Hey I also use the same method to split large class in flutter, everything is as intended only problem is that if setstate is called from extended class, it works fine but a warning is given - The member 'setState' can only be used within instance members of subclasses of 'package:flutter/src/widgets/framework.dart'. Commented Feb 9 at 8:25
19

Dart doesn't support partial classes. part and part of are to split a library into multiple files, not a class.

Private (identifiers starting with _) in Dart is per library which is usually a *.dart file.

main.dart

part 'part.dart';

class Test {
  /// When someone tries to create an instance of this class
  /// Create an instance of _Test instead
  factory Test() = _Test;

  /// private constructor that can only be accessed within the same library
  Test._(); 

  static const   a = 10;
  final b = 20;
  final c = a+1;
}

part.dart

part of 'main.dart';
class _Test extends Test {
  /// private constructor can only be called from within the same library
  /// Call the private constructor of the super class
  _Test() : super._();

  /// static members of other classes need to be prefixed with
  /// the class name, even when it is the super class
  final d = Test.a +1;   //<---undefined name 'a'
} 

A similar pattern is used in many code-generation scenarios in Dart like in

and many others.

15
  • I got the following error in fultter: The return type 'Test' of the redirected constructor isn't assignable to 'Test'. The class 'Object' doesn't have a constructor named ''.
    – camino
    Commented Apr 1, 2018 at 15:18
  • Sorry, I forgot to add extends Test - fixed Commented Apr 1, 2018 at 15:19
  • 1
    Thanks, it works now! So if I want to split class Test into multiple file, just create multiple classes which extend from Test, right?
    – camino
    Commented Apr 1, 2018 at 15:22
  • It depends on why you want to split it. Above pattern is (as mentioned) used for code generation, where one file is hand-written and the other is generated automatically. For purely hand-written classes this shouldn't be necessary. If classes become too big you probably need specialize your classes mire. Commented Apr 1, 2018 at 15:25
  • Is it possible to use part not in library as well? I had tried but w/o success.
    – BambinoUA
    Commented Jan 7, 2022 at 7:15
6

I just extend it with extension keyword like Swift.

// class_a.dart
class ClassA {}

// class_a+feature_a.dart
import 'class_a.dart';    

extension ClassA_FeatureA on ClassA {
  String separatedFeatureA() {
    // do your job here
  }
}

Please ignore the coding conventions, it's just a sample.

0

I learn from tutorial way, select a class name and use Refactor menu, choose Move XXXClass to file, it will auto generate new file and insert import to your code.

tutorial: https://codelabs.developers.google.com/codelabs/flutter-codelab-first?hl=zh-cn#4

IDE: vscode

Open Refactor shortcut (Mac): CMD + .

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.