katana_listenables 2.2.11 copy "katana_listenables: ^2.2.11" to clipboard
katana_listenables: ^2.2.11 copied to clipboard

The base part of the package that allows Listenable values to be grouped together and treated as a ChangeNotifier.

Masamune logo

Katana Listenables

Follow on Twitter Follow on Threads Maintained with Melos

GitHub Sponsor


[GitHub] | [YouTube] | [Packages] | [Twitter] | [Threads] | [LinkedIn] | [mathru.net]


Introduction #

You may want to manage multiple TextEditingControllers, ValueNotifiers, and other controllers that inherit these ChangeNotifiers when creating widgets.

It would then generally look something like the following.

  • Define multiple ChangeNotifier inherited classes in State
  • Create a class inheriting from ChangeNotifier for use in the state management package and addListener for all

I have created the following package to simplify the above implementation.

  • Create a class inheriting from ChageNotofier with a simple description
  • Monitor its parameters by passing an object inheriting from ChageNotofier as a parameter.
    • When a change occurs in a monitored ChageNotifier, the change is propagated to its own object.

For example, the following statement is used

@listenables
class ControllerGroup with _$ControllerGroup, ChangeNotifier {
  factory ControllerGroup({
    required TextEditingController emailTextEditingController,
    required TextEditingController passwordTextEditingController,
    required FocusNode focusNode,
    ValueNotifier<bool> checkTerms,
  }) = _ControllerGroup;
}

When build_runner is run with this, a class inheriting from ChangeNotifier (Listenable) given as an argument is automatically generated.

If you load this in riverpod, for example, as follows…

final controllerProvider = ChangeNotifierProvider((_) {
  return ControllerGroup(
    emailTextEditingController: TextEdigingController(),
    passwordTextEditingController: TextEdigingController(),
    focusNode: FocusNode(),
    checkTerms: ValueNotifier(false),
 );
});

class TestPage extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref){
    final controller = ref.watch(controllerProvider);

    ~~~~
    controller.emailTextEditingController.text = "New Text"; // At this time, the controller is also notified of the change and the widget is updated again.
    ~~~~
  }
}

When the contents of emailTextEditingController defined in the controller are updated, the change notification is propagated to the controller as well.

Since the controller is also a ChangeNotifier, changes can be monitored by addListener, etc.

Installation #

Import the following package for code generation using build_runner.

flutter pub add katana_listenables
flutter pub add --dev build_runner
flutter pub add --dev katana_listenables_builder

Implementation #

Make a Class #

Create a class as follows

Add part '(filename).listenable.dart';.

Annotate the defined class with @listenables and mixin _$(defined class name) and ChangeNotifier.

The constructor is created in the factory and defines classes that inherit from ChangeNotifier and Listenable that you want to use in the parameters.

(Required values are marked "required"; if "required" is not marked, leave it as it is.)

After the constructor, write = _ (the name of the defined class).

// controller.dart

import 'package:flutter/material.dart';
import 'package:katana_listenables/katana_listenables.dart';

part 'controller.listenable.dart';

@listenables
class ControllerGroup with _$ControllerGroup, ChangeNotifier {
  factory ControllerGroup({
    required TextEditingController emailTextEditingController,
    required TextEditingController passwordTextEditingController,
    required FocusNode focusNode,
    ValueNotifier<bool> checkTerms,
  }) = _ControllerGroup;
}

Code Generation #

Automatic code generation is performed by entering the following command.

flutter pub run build_runner build --delete-conflicting-outputs

How to use #

Since the created class inherits from ChangeNotifier, it can be used in the same way as a general ChangeNotifier.

  • For State
class TestPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState => TestPageState();
}

class TestPageState extends State<TestPage> {
  final controller = ControllerGroup(
    emailTextEditingController: TextEdigingController(),
    passwordTextEditingController: TextEdigingController(),
    focusNode: FocusNode(),
    checkTerms: ValueNotifier(false),
  );

  @override
  void initState(){
    super.initState();
    controller.addListener(_handledOnUpdate);
  }
	
  void _handledOnUpdate(){
    setState((){});
  }

  @override
  void dispose(){
    super.dispose();
    controller.removeListener(_handledOnUpdate);
    controller.dispose();
  }

  @override
  Widget build(BuildContext context, WidgetRef ref){
    final controller = ref.watch(controllerProvider);

    ~~~~
    controller.emailTextEditingController.text = "New Text"; // At this time, the controller is also notified of the change and the widget is updated again.
    ~~~~
  }
}
  • For riverpod
final controllerProvider = ChangeNotifierProvider((_) {
  return ControllerGroup(
    emailTextEditingController: TextEdigingController(),
    passwordTextEditingController: TextEdigingController(),
    focusNode: FocusNode(),
    checkTerms: ValueNotifier(false),
  );
});

class TestPage extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref){
    final controller = ref.watch(controllerProvider);

    ~~~~
    controller.emailTextEditingController.text = "New Text"; // At this time, the controller is also notified of the change and the widget is updated again.
    ~~~~
  }
}

Additional Usage #

Adding Methods #

To add a method, use the following writing style.

(defined class name). _(); constructor must be added.

// controller.dart

import 'package:flutter/material.dart';
import 'package:katana_listenables/katana_listenables.dart';

part 'controller.listenable.dart';

@listenables
class ControllerGroup with _$ControllerGroup, ChangeNotifier {
  factory ControllerGroup({
    required TextEditingController emailTextEditingController,
    required TextEditingController passwordTextEditingController,
    required FocusNode focusNode,
    ValueNotifier<bool> checkTerms,
  }) = _ControllerGroup;
  ControllerGroup._(); // Additional Required

  bool checked {
    return checkTerms?.value ?? false;
  }
}

GitHub Sponsors #

Sponsors are always welcome. Thank you for your support!

https://github.com/sponsors/mathrunet

1
likes
160
points
5.32k
downloads

Publisher

verified publishermathru.net

Weekly Downloads

The base part of the package that allows Listenable values to be grouped together and treated as a ChangeNotifier.

Homepage
Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter, katana, katana_listenables_annotation

More

Packages that depend on katana_listenables