themaaz32 / hive_todo_teach

MIT License
13 stars 7 forks source link

valueListenable: todoBox.listenable() here error happen #1

Open wann2 opened 4 years ago

wann2 commented 4 years ago

lib/screens/scr_todo.dart:83:38: Error: The method 'listenable' isn't defined for the class 'Box'.

Hi, I followed your sources, but an error happens that listenable() is undefined

main.dart const String todoBoxNm = "todo";

void main() async { WidgetsFlutterBinding.ensureInitialized(); Directory document = await getApplicationDocumentsDirectory(); Hive.init(document.path); Hive.registerAdapter(TodoModelAdapter()); await Hive.openBox(todoBoxNm);

runApp(MyApp()); } ...... onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (_) => TodoMain(),),), ......

scr_todo.dart import 'dart:io';

import 'package:emochat/models/modelTodo.dart'; import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; import 'package:path_provider/path_provider.dart'; import 'package:hive_flutter/hive_flutter.dart';

import '../main.dart';

//const String todoBoxName = "todo";

class TodoMain extends StatefulWidget { @override _TodoMainState createState() => _TodoMainState(); }

enum TodoFilter { ALL, COMPLETED, INCOMPLETED }

class _TodoMainState extends State { Box todoBox;

final TextEditingController titleController = TextEditingController(); final TextEditingController detailController = TextEditingController();

TodoFilter filter = TodoFilter.ALL;

@override void initState() { super.initState(); todoBox = Hive.box(todoBoxNm); }

@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Hive Todo"), actions: [ PopupMenuButton( onSelected: (value) { if (value.compareTo("All") == 0) { setState(() { filter = TodoFilter.ALL; }); } else if (value.compareTo("Compeleted") == 0) { setState(() { filter = TodoFilter.COMPLETED; }); } else { setState(() { filter = TodoFilter.INCOMPLETED; }); } }, itemBuilder: (BuildContext context) { return ["All", "Compeleted", "Incompleted"].map((option) { return PopupMenuItem( value: option, child: Text(option), ); }).toList(); }, ) ], ),

  body: Column(
    children: <Widget>[
      ValueListenableBuilder(
        valueListenable: todoBox.listenable(),
        builder: (context, Box<TodoModel> todos, _) {
          List<int> keys;

          if (filter == TodoFilter.ALL) {
            keys = todos.keys.cast<int>().toList();
          } else if (filter == TodoFilter.COMPLETED) {
            keys = todos.keys
                .cast<int>()
                .where((key) => todos.get(key).isCompleted)
                .toList();
          } else {
            keys = todos.keys
                .cast<int>()
                .where((key) => !todos.get(key).isCompleted)
                .toList();
          }

          return ListView.separated(
            itemBuilder: (_, index) {
              final int key = keys[index];
              final TodoModel todo = todos.get(key);

              return ListTile(
                title: Text(
                  todo.title,
                  style: TextStyle(fontSize: 24),
                ),
                subtitle: Text(todo.detail, style: TextStyle(fontSize: 20)),
                leading: Text("$key"),
                trailing: Icon(
                  Icons.check,
                  color: todo.isCompleted ? Colors.green : Colors.red,
                ),
                onTap: () {
                  showDialog(
                      context: context,
                      child: Dialog(
                          child: Container(
                        padding: EdgeInsets.all(16),
                        child: Column(
                          mainAxisSize: MainAxisSize.min,
                          children: <Widget>[
                            FlatButton(
                              child: Text("Mark as completed"),
                              onPressed: () {
                                TodoModel mTodo = TodoModel(
                                    title: todo.title,
                                    detail: todo.detail,
                                    isCompleted: true);

                                todoBox.put(key, mTodo);

                                Navigator.pop(context);
                              },
                            )
                          ],
                        ),
                      )));
                },
              );
            },
            separatorBuilder: (_, index) => Divider(),
            itemCount: keys.length,
            shrinkWrap: true,
          );
        },
      )
    ],
  ),

  floatingActionButton: FloatingActionButton(
    onPressed: () {
      showDialog(
          context: context,
          child: Dialog(
              child: Container(
            padding: EdgeInsets.all(16),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                TextField(
                  decoration: InputDecoration(hintText: "Title"),
                  controller: titleController,
                ),
                SizedBox(
                  height: 8,
                ),
                TextField(
                  decoration: InputDecoration(hintText: "Detail"),
                  controller: detailController,
                ),
                SizedBox(
                  height: 8,
                ),
                FlatButton(
                  child: Text("Add Todo"),
                  onPressed: () {
                    final String title = titleController.text;
                    final String detail = detailController.text;

                    TodoModel todo = TodoModel(
                        title: title, detail: detail, isCompleted: false);

                    todoBox.add(todo);

                    Navigator.pop(context);
                  },
                )
              ],
            ),
          )));
    },
    child: Icon(Icons.add),
  ),
);

} }

themaaz32 commented 4 years ago

See comments on the videos. I answered that.

Thanks.

On Tue, May 12, 2020, 12:48 PM wann2 notifications@github.com wrote:

lib/screens/scr_todo.dart:83:38: Error: The method 'listenable' isn't defined for the class 'Box'.

  • 'Box' is from 'package:hive/hive.dart' ('../../../../Documents/flutter/.pub-cache/hosted/ pub.dartlang.org/hive-1.4.1+1/lib/hive.dart').
  • 'TodoModel' is from 'package:emochat/models/modelTodo.dart' ('lib/models/modelTodo.dart'). Try correcting the name to the name of an existing method, or defining a method named 'listenable'. valueListenable: todoBox.listenable(), ^^^^^^^^^^

main.dart const String todoBoxNm = "todo";

void main() async { WidgetsFlutterBinding.ensureInitialized(); Directory document = await getApplicationDocumentsDirectory(); Hive.init(document.path); Hive.registerAdapter(TodoModelAdapter()); await Hive.openBox(todoBoxNm);

runApp(MyApp()); } ......

scr_todo.dart import 'dart:io';

import 'package:emochat/models/modelTodo.dart'; import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; import 'package:path_provider/path_provider.dart'; import 'package:hive_flutter/hive_flutter.dart';

import '../main.dart';

//const String todoBoxName = "todo";

class TodoMain extends StatefulWidget { @override https://github.com/override _TodoMainState createState() => _TodoMainState(); }

enum TodoFilter { ALL, COMPLETED, INCOMPLETED }

class _TodoMainState extends State { Box todoBox;

final TextEditingController titleController = TextEditingController(); final TextEditingController detailController = TextEditingController();

TodoFilter filter = TodoFilter.ALL;

@override https://github.com/override void initState() { super.initState(); todoBox = Hive.box(todoBoxNm); }

@override https://github.com/override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Hive Todo"), actions: [ PopupMenuButton( onSelected: (value) { if (value.compareTo("All") == 0) { setState(() { filter = TodoFilter.ALL; }); } else if (value.compareTo("Compeleted") == 0) { setState(() { filter = TodoFilter.COMPLETED; }); } else { setState(() { filter = TodoFilter.INCOMPLETED; }); } }, itemBuilder: (BuildContext context) { return ["All", "Compeleted", "Incompleted"].map((option) { return PopupMenuItem( value: option, child: Text(option), ); }).toList(); }, ) ], ),

body: Column( children: [ ValueListenableBuilder( valueListenable: todoBox.listenable(), builder: (context, Box todos, _) { List keys;

      if (filter == TodoFilter.ALL) {
        keys = todos.keys.cast<int>().toList();
      } else if (filter == TodoFilter.COMPLETED) {
        keys = todos.keys
            .cast<int>()
            .where((key) => todos.get(key).isCompleted)
            .toList();
      } else {
        keys = todos.keys
            .cast<int>()
            .where((key) => !todos.get(key).isCompleted)
            .toList();
      }

      return ListView.separated(
        itemBuilder: (_, index) {
          final int key = keys[index];
          final TodoModel todo = todos.get(key);

          return ListTile(
            title: Text(
              todo.title,
              style: TextStyle(fontSize: 24),
            ),
            subtitle: Text(todo.detail, style: TextStyle(fontSize: 20)),
            leading: Text("$key"),
            trailing: Icon(
              Icons.check,
              color: todo.isCompleted ? Colors.green : Colors.red,
            ),
            onTap: () {
              showDialog(
                  context: context,
                  child: Dialog(
                      child: Container(
                    padding: EdgeInsets.all(16),
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      children: <Widget>[
                        FlatButton(
                          child: Text("Mark as completed"),
                          onPressed: () {
                            TodoModel mTodo = TodoModel(
                                title: todo.title,
                                detail: todo.detail,
                                isCompleted: true);

                            todoBox.put(key, mTodo);

                            Navigator.pop(context);
                          },
                        )
                      ],
                    ),
                  )));
            },
          );
        },
        separatorBuilder: (_, index) => Divider(),
        itemCount: keys.length,
        shrinkWrap: true,
      );
    },
  )
],

),

floatingActionButton: FloatingActionButton( onPressed: () { showDialog( context: context, child: Dialog( child: Container( padding: EdgeInsets.all(16), child: Column( mainAxisSize: MainAxisSize.min, children: [ TextField( decoration: InputDecoration(hintText: "Title"), controller: titleController, ), SizedBox( height: 8, ), TextField( decoration: InputDecoration(hintText: "Detail"), controller: detailController, ), SizedBox( height: 8, ), FlatButton( child: Text("Add Todo"), onPressed: () { final String title = titleController.text; final String detail = detailController.text;

                TodoModel todo = TodoModel(
                    title: title, detail: detail, isCompleted: false);

                todoBox.add(todo);

                Navigator.pop(context);
              },
            )
          ],
        ),
      )));
},
child: Icon(Icons.add),

), );

} }

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/themaaz32/hive_todo_teach/issues/1, or unsubscribe https://github.com/notifications/unsubscribe-auth/AMBNJJIUTCANZSOSQLAGPH3RRD5LHANCNFSM4M6SS7RQ .

wann2 commented 4 years ago

I imported hive_flutter.dart like the below, but the font color is gray. import 'package:hive_flutter/hive_flutter.dart';

I watched the video in detail, but I could not figure out what is wrong. The difference is that I separated a main.dart into 2 dart file(main.dart and scr_todo.dart).

In scr_todo.dart, valueListenable: todoBox.listenable() An error happen that listenable() is not defined.

pubspec.yaml environment: sdk: ">=2.5.0 <3.0.0"

dependencies: flutter: sdk: flutter hive: ^1.4.1+1 hive_flutter:

dev_dependencies: flutter_test: sdk: flutter hive_generator: build_runner:

When I input the version of hive_flutter, then the below error happens. so I did not input it the above and no error. hive_flutter: ^0.3.0+2

_Because emochat depends on hiveflutter ^0.3.0+2 which depends on path >=1.6.0 <1.7.0, path >=1.6.0 <1.7.0 is required. So, because emochat depends on path ^1.7.0, version solving failed. pub get failed (1; So, because emochat depends on path ^1.7.0, version solving failed.)

And I generated modelTodo.g.dart part of 'modelTodo.dart'; class TodoModelAdapter extends TypeAdapter { @override TodoModel read(BinaryReader reader) { var numOfFields = reader.readByte(); var fields = <int, dynamic>{ for (var i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), }; return TodoModel( title: fields[0] as String, detail: fields[1] as String, isCompleted: fields[2] as bool, ); }

@override void write(BinaryWriter writer, TodoModel obj) { writer ..writeByte(3) ..writeByte(0) ..write(obj.title) ..writeByte(1) ..write(obj.detail) ..writeByte(2) ..write(obj.isCompleted); }

@override int get typeId { //throw UnimplementedError(); } }

wann2 commented 4 years ago

I remarked the below, not it can execute pub get with no error.

dev_dependencies:

flutter_test:

sdk: flutter

But another thing!

TodoModelAdapter class has a red line and it request that an unimplemented method should be implemented like the below.

@override int get typeId => throw UnimplementedError();

When I added it inside TodoModelAdapter class, then Unhandled Exception: UnimplementedError happens. so i changed it into the below.

@override int get typeId { //throw UnimplementedError(); }

But now I got "Unhandled Exception: NoSuchMethodError: The method '<' was called on null." from Hive.registerAdapter(TodoModelAdapter());