Flutter FutureBuilder, StreamBuilder, Form vs.

Flutter FutureBuilder, StreamBuilder, Form vs.

 Videolu anlatım: https://youtu.be/H8cyZtzkSY4

//pubspec.yaml

name: futurestreambuilderornek
description: A new Flutter project.

# The following line prevents the package from being accidentally published to
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev

# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1

environment:
  sdk: ">=2.7.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  signal: ^0.2.2+1
  validators: ^2.0.1
  regexed_validator: ^1.0.4 
  
  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.3

dev_dependencies:
  flutter_test:
    sdk: flutter

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

# The following section is specific to Flutter.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  # To add assets to your application, add an assets section, like this:
  # assets:
  #   - images/a_dot_burr.jpeg
  #   - images/a_dot_ham.jpeg

  # An image asset can refer to one or more resolution-specific "variants", see
  # https://flutter.dev/assets-and-images/#resolution-aware.

  # For details regarding adding assets from package dependencies, see
  # https://flutter.dev/assets-and-images/#from-packages

  # To add custom fonts to your application, add a fonts section here,
  # in this "flutter" section. Each entry in this list should have a
  # "family" key with the font family name, and a "fonts" key with a
  # list giving the asset and other descriptors for the font. For
  # example:
  # fonts:
  #   - family: Schyler
  #     fonts:
  #       - asset: fonts/Schyler-Regular.ttf
  #       - asset: fonts/Schyler-Italic.ttf
  #         style: italic
  #   - family: Trajan Pro
  #     fonts:
  #       - asset: fonts/TrajanPro.ttf
  #       - asset: fonts/TrajanPro_Bold.ttf
  #         weight: 700
  #
  # For details regarding fonts from package dependencies,
  # see https://flutter.dev/custom-fonts/#from-packages
 
//mxVopForm.dart

import 'package:flutter/material.dart';

mixin MxVopForm {

  String mxValidator(bool isValidate, String errorText) =>
      isValidate ? null : errorText;

  String mxOnSaved(String value) => value.trim();

  mxSaveForm(GlobalKey<FormState> formKey,  Function() onSavedForm) {
    if (formKey?.currentState?.validate() ?? false) {
      formKey?.currentState?.save();
      onSavedForm?.call();
    }
  }
}



//mxVopValidators.dart

import 'package:regexed_validator/regexed_validator.dart';
import 'package:validators/validators.dart';

mixin MxVopIsEmail {
  
  bool mxIsEmail(dynamic value) {
    try {
      return isEmail(value.trim());
    } catch (e) {
      return false;
    }
  }
}

mixin MxVopIsLength {
  bool mxIsLength(dynamic value, int min, [int max]) {
    try {
      return isLength(value.trim(), min, max);
    } catch (e) {
      return false;
    }
  }
}

mixin MxVopIsPhone {
  bool mxIsPhone(dynamic value) {
    try {
      return validator.phone(value.trim());
    } catch (e) {
      return false;
    }
  }
}


mixin MxVopIsUrl {
 
  bool mxIsUrl(dynamic url) {
    if(url == null) return false;
    try {
      return isURL(url.trim());
    } catch (e) {
      return false;
    }
  }
}

mixin MxVopIsEquals {
 
  bool mxIsEquals(String str, dynamic comparison) {
    try {
      return equals(str.trim(),comparison.trim());
    } catch (e) {
      return false;
    }
  }
}

  
//RandomGenerate.dart

import 'dart:math';
import 'dart:ui';

class RandomGenerate {
  static int getInt(int minValue, int maxValue) => Random().nextInt((maxValue - minValue).abs() + 1) +  min(minValue, maxValue);
  static bool getBool() => Random().nextBool();
  static int getHex() => getInt(0xFF0587D8, 0xFF0345B5);
  static Color getColor() => Color(getHex());
  static String getTitle() => capitalize(nouns[Random().nextInt(nouns.length)]);
  static String capitalize(String s) => s[0].toUpperCase() + s.substring(1);
}

const List<String> nouns = [
  'time',
  'year',
  'people',
  'way',
  'day',
  'man',
  'thing',
  'woman',
  'life',
  'child',
  'world',
  'school',
  'state',
  'family',
  'student',
  'group',
  'country',
  'problem',
  'hand',
  'part',
  'place',
  'case',
  'week',
  'company',
  'system',
  'program',
  'question',
  'work',
  'government',
  'number',
  'night',
  'point',
  'home',
  'water',
  'room',
  'mother',
  'area',
  'money',
  'story',
  'fact',
  'month',
  'lot',
  'right',
  'study',
  'book',
  'eye',
  'job',
  'word',
  'business',
  'issue',
  'side',
  'kind',
  'head',
  'house',
  'service',
  'friend',
  'father',
  'power',
  'hour',
  'game',
  'line',
  'end',
  'member',
  'law',
  'car',
  'city',
  'community',
  'name',
  'president',
  'team',
  'minute',
  'idea',
  'kid',
  'body',
  'information',
  'back',
  'parent',
  'face',
  'others',
  'level',
  'office',
  'door',
  'health',
  'person',
  'art',
  'war',
  'history',
  'party',
  'result',
  'change',
  'morning',
  'reason',
  'research',
  'girl',
  'guy',
  'food',
  'moment',
  'air',
  'teacher',
  'force',
  'education',
  'foot',
  'boy',
  'age',
  'policy',
  'process',
  'music',
  'market',
  'sense',
  'nation',
  'plan',
  'college',
  'interest',
  'death',
  'experience',
  'effect',
  'use',
  'class',
  'control',
  'care',
  'field',
  'development',
  'role',
  'effort',
  'rate',
  'heart',
  'drug',
  'show',
  'leader',
  'light',
  'voice',
  'wife',
  'police',
  'mind',
  'price',
  'report',
  'decision',
  'son',
  'view',
  'relationship',
  'town',
  'road',
  'arm',
  'difference',
  'value',
  'building',
  'action',
  'model',
  'season',
  'society',
  'tax',
  'director',
  'position',
  'player',
  'record',
  'paper',
  'space',
  'ground',
  'form',
  'event',
  'official',
  'matter',
  'center',
  'couple',
  'site',
  'project',
  'activity',
  'star',
  'table',
  'need',
  'court',
  'American',
  'oil',
  'situation',
  'cost',
  'industry',
  'figure',
  'street',
  'image',
  'phone',
  'data',
  'picture',
  'practice',
  'piece',
  'land',
  'product',
  'doctor',
  'wall',
  'patient',
  'worker',
  'news',
  'test',
  'movie',
  'north',
  'love',
  'support'
];

  
//stWsChangeable.dart

import 'dart:async';
import 'package:signal/signal.dart';

class StWsChangeable extends BaseState {
  StWsChangeable(void Function() onStateChanged) : super(onStateChanged);
  String _formText;
  String _text;
  bool _showForm;
  String get text => _text;
  bool get showForm => _showForm;
  String get formText => _formText;

  @override
  void initState({String nText, bool nshowForm = false}) {
    _showForm = nshowForm;
    _text = nText;
  }

  setShowForm(bool value) {
    _showForm = value;
    doneSucces();
  }

  Future<String> initFuture() async => await Future.delayed(
      Duration(seconds: 2), () => 'İlk  future değer geldi');

  String onSaved(String value) => _formText = value.trim();

  Future<void> onSavedForm(
      {FutureOr<void> Function(String value) onSaved,
      void Function(String value) onDoneSuccess}) async {
    try {
      wait();

      await Future.value(onSaved(formText));
      _showForm = false;
      _text = formText;

      doneSucces();
      onDoneSuccess?.call(text);
    } catch (e) {
      _showForm = true;
      doneError(e.toString());
    }
  }

  @override
  Future<void> afterInitState({Future<String> Function() future}) async {
    try {
      var tempText = await future?.call();
      if (tempText != null) _text = tempText;

      doneSucces();
    } catch (e) {
      doneError(e.toString());
    }
  }

  @override
  void dispose() {
    // TODO: implement dispose
  }
}
 
//wsChangeableText.dart

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

class WsChangeableText extends StatefulWidget {
  const WsChangeableText({
    Key key,
    this.future,
    this.text,
    this.icon,
    @required this.labelText,
    @required this.onValidator,
    @required this.onSavedForm,
    this.onDoneSuccess,
    this.keyboardType,
  })  : assert(labelText != null),
        assert(onValidator != null),
        assert(onSavedForm != null),
        super(key: key);

  final Future<String> Function() future;
  final String text;
  final Widget icon;
  final String labelText;
  final String Function(String value) onValidator;
  final void Function(String value) onSavedForm;
  final void Function(String value) onDoneSuccess;
  final TextInputType keyboardType;
  @override
  _WsChangeableTextState createState() => _WsChangeableTextState();
}

class _WsChangeableTextState extends State<WsChangeableText> {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  StWsChangeable _state;
  StWsChangeable get state => _state;

  @override
  void initState() {
    super.initState();

    _state = StWsChangeable(() {
      if (mounted) {
        setState(() {});
      }
    })
      ..initState(nText: widget.text);
    if (widget.future != null){
      state.wait(signal:false);
       state.afterInitState(future: widget.future);
    }
  }

  @override
  void didUpdateWidget(WsChangeableText oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.text != widget.text) {
      _state.initState(nText: widget.text);
      _state.doneSucces(signal: false);
    }
  }

  @override
  Widget build(BuildContext context) {

    return Center(
      child: !state.showForm
          ? state.busy
              ? CircularProgressIndicator(strokeWidth: 2)
              : !state.success
                  ? Text('Hata : ${state.error} ')
                  : ListTile(
                      leading: widget.icon ??
                          SizedBox(
                            width: 0,
                            height: 0,
                          ),
                      title: Text(state.text ?? ''),
                      onTap: () => state.setShowForm(true),
                    )
          : Stack(alignment: Alignment.center, children: [
              AbsorbPointer(
                absorbing: state.busy,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      mainAxisSize: MainAxisSize.min,
                      children: <Widget>[
                        Expanded(
                          child: Form(
                            key: _formKey,
                            child: TextFormField(
                              enabled: !state.busy,
                              autofocus: true,
                              keyboardType:
                                  widget.keyboardType ?? TextInputType.text,
                              decoration: InputDecoration(
                                  border: const OutlineInputBorder(),
                                  icon: widget.icon ??
                                      SizedBox(
                                        width: 0,
                                        height: 0,
                                      ),
                                  labelText: widget.labelText),
                              validator: (value) => widget.onValidator(value),
                              onSaved: (value) => state.onSaved(value),
                            ),
                          ),
                        ),
                        SizedBox(
                          width: 10,
                        ),
                        Expanded(
                          child: RaisedButton(
                            child: Text(
                              "Ok",
                              style: TextStyle(
                                  color: Colors.lightBlue, fontSize: 15),
                            ),
                            onPressed: () {
                              if (_formKey.currentState.validate()) {
                                _formKey.currentState.save();
                                state.onSavedForm(
                                    onSaved: widget.onSavedForm,
                                    onDoneSuccess: widget.onDoneSuccess);
                              }
                            },
                          ),
                        ),
                        SizedBox(
                          width: 10,
                        ),
                        Expanded(
                          child: RaisedButton(
                            child: Text(
                              "Vazgeç",
                              style: TextStyle(
                                  color: Colors.lightBlue, fontSize: 15),
                            ),
                            onPressed: () => state.setShowForm(false),
                          ),
                        ),
                      ],
                    ),
                    if (!state.success && !state.busy)
                      Text(
                        'stLocalization.getTranslated(state.error)' +
                            state.error,
                        style: TextStyle(color: Colors.red),
                      )
                  ],
                ),
              ),
              if (state.busy) CircularProgressIndicator(strokeWidth: 2),
            ]),
    );
  }
}
 
//main.dart

import 'package:flutter/material.dart';

import 'Mx/mxVop/mxVopForm.dart';
import 'Mx/mxVop/mxVopValidators.dart';
import 'test/RandomGenerate.dart';
import 'wsChangeableText.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}




class _Op with MxVopForm, MxVopIsLength {}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}
 

class _MyHomePageState extends State<MyHomePage> {
  String _title = 'parent ilk data';
  String get title => _title;
  final _op = _Op();

  set title(String title) {
    setState(() {
      _title = title;
    });
  }
 
  Future<void> updateTitle(String value) async {
    await Future.delayed(Duration(seconds: 2), () {
      _title = value;
    });
  }

  Future<String> future() async {
    return await Future.delayed(Duration(seconds: 5), () {
      return _title = 'future ilk data';
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('MyHomePage'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
           
            WsChangeableText(
              future: future ,
              text: _title,
              icon: Icon(Icons.account_circle),
              onDoneSuccess: (value) {
                title = value;
              },
              labelText: 'Name',
              onValidator: (value) => _op.mxValidator(_op.mxIsLength(value, 5),
                  'En az 5 karekter uzunluğunda olmalı!'),
              onSavedForm: updateTitle,
            ),
            // Text('Parent title : ' + title),
            
            FutureBuilder<String>(
              // initialData: title,
                future: future() ,
                builder: (context, snapshot) {
         if (snapshot.hasData)  
          return Text('FutureBuilder title : ' + snapshot.data);
           else if (snapshot.hasError) 
          return  Text('FutureBuilder Hata: ' + snapshot.error);
            else  
          return  Text('FutureBuilder Veri getiriliyor..');
                })
                
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            title = RandomGenerate.getTitle();
     
          });
        },
        tooltip: 'Değiştir',
        child: Icon(Icons.add),
      ),
    );
  }
}
 

Bir cevap yazın