shuvigoss / coss_demo

coss_demo
1 stars 0 forks source link

从零开始学习Flutter【五】 #5

Open shuvigoss opened 4 years ago

shuvigoss commented 4 years ago

这节课学习bloc相关只是。

首先在pubspec.yaml引入

  equatable: ^1.2.0
  flutter_bloc: ^4.0.1

然后引入插件自动生成代码

https://plugins.jetbrains.com/plugin/12129-bloc/

image

shuvigoss commented 4 years ago

生成代码并填充逻辑

bloc.dart

export 'config_bloc.dart';
export 'config_event.dart';
export 'config_state.dart';

config_bloc.dart

import 'dart:async';

import 'package:bloc/bloc.dart';
import 'package:coss_demo/pages/utils/store_helper.dart';

import './bloc.dart';

class ConfigBloc extends Bloc<ConfigEvent, ConfigState> {
  @override
  ConfigState get initialState => InitialConfigState();

  @override
  Stream<ConfigState> mapEventToState(
    ConfigEvent event,
  ) async* {
    if (event is Fetch) {
      try {
        final all = await StoreHelper.getAll();
        yield Loaded(items: all);
      } catch (e) {
        print(e);
        yield Failure();
      }
    }

    if (event is Add) {
      try {
        await StoreHelper.add(event.item);
        yield Loaded(items: await StoreHelper.getAll());
      } catch (e) {
        print(e);
        yield Failure();
      }
    }

    if (event is Delete) {
      try {
        await StoreHelper.del(event.name);
        yield Loaded(items: await StoreHelper.getAll());
      } catch (e) {
        print(e);
        yield Failure();
      }
    }
  }
}

config_event.dart

import 'package:coss_demo/pages/models/config_item.dart';
import 'package:equatable/equatable.dart';

abstract class ConfigEvent extends Equatable {
  const ConfigEvent();

  @override
  List<Object> get props => [];
}

class Fetch extends ConfigEvent {}

class Add extends ConfigEvent {
  final ConfigItem item;

  const Add(this.item);
}

class Delete extends ConfigEvent {
  final String name;

  const Delete(this.name);
}

config_state.dart

import 'package:coss_demo/pages/models/config_item.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/cupertino.dart';

abstract class ConfigState extends Equatable {
  const ConfigState();

  @override
  List<Object> get props => [];
}

class InitialConfigState extends ConfigState {
  @override
  List<Object> get props => [];
}

class Loading extends ConfigState {}

class Loaded extends ConfigState {
  final List<ConfigItem> items;

  const Loaded({@required this.items});
}

class Failure extends ConfigState {}
shuvigoss commented 4 years ago

修改 config_index.dart

import 'package:coss_demo/bloc/bloc.dart';
import 'package:coss_demo/pages/widgets/image_btn.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class ConfigIndexPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('服务列表'),
        ),
        body: Container(
          child: Column(
            children: <Widget>[buildTop(context), buildConfigList()],
          ),
        ));
  }

  Expanded buildConfigList() {
    return Expanded(
      child: Container(
        margin: EdgeInsets.only(top: 10),
        color: Colors.white,
        child: BlocBuilder<ConfigBloc, ConfigState>(builder: (context, state) {
          if (state is Failure) {
            return Center(child: Text('加载异常了...'));
          }

          if (state is Loaded) {
            if (state.items.length == 0) {
              return Center(child: Text('暂无数据'));
            }

            return Container(
                child: ListView.separated(
                    itemBuilder: (context, index) {
                      return ListTile(
                        leading: Image.asset('images/fuwuliebiao.png'),
                        title: Text(state.items[index].name),
                        subtitle: Text(state.items[index].url),
                        trailing: IconButton(
                          onPressed: () =>
                              delete(context, state.items[index].name),
                          icon: Icon(Icons.delete),
                        ),
                      );
                    },
                    separatorBuilder: (context, index) {
                      return Divider(
                        height: 1,
                      );
                    },
                    itemCount: state.items.length));
          } else {
            return Center(
              child: CircularProgressIndicator(),
            );
          }
        }),
      ),
    );
  }

  Container buildTop(context) {
    return Container(
      color: Colors.white,
      height: 135,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          Container(
            child: ImageBtn('images/shoudongluru.png', '手动录入', () {
              Navigator.pushNamed(context, '/config');
            }),
          ),
          Container(
            width: 0.5,
            color: Colors.grey,
          ),
          Container(
            child: ImageBtn('images/saomatianjia.png', '扫码添加', () {
              print('shoudongluru');
            }),
          )
        ],
      ),
    );
  }

  delete(BuildContext context, String name) {
    BlocProvider.of<ConfigBloc>(context).add(Delete(name));
  }
}

修改main.dart

import 'package:coss_demo/pages/config.dart';
import 'package:coss_demo/pages/welcome.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import 'bloc/config_bloc.dart';
import 'bloc/config_event.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MultiBlocProvider(
        providers: [
          BlocProvider<ConfigBloc>(
            create: (context) => ConfigBloc()..add(Fetch()),
          )
        ],
        child: MaterialApp(
          title: '协同签名',
          home: WelcomePage(),
          theme: ThemeData(
              primaryColor: Colors.white,
              scaffoldBackgroundColor: Color.fromRGBO(248, 248, 248, 1)),
          routes: {'/config': (context) => ConfigPage()},
        ));
  }
}

修改config.dart

  _submit(context) {
    if ((_key.currentState as FormState).validate()) {
      BlocProvider.of<ConfigBloc>(context)
          .add(Add(ConfigItem(_btext.text, _stext.text)));
      Navigator.pop(context);
    }
  }