ChangeNotifierProvider不会创建新的ChangeNotifier实例

时间:2020-05-19 08:40:54

标签: flutter flutter-provider flutter-change-notifier

我有一个平板电脑的“详细信息”页面。
在列表中选择一个项目时,我想更改详细信息页面。
所以我写了这样的代码,

class AttendancesModel with ChangeNotifier {
  final int userId;
  AttendancesModel(this.userId);

  List<Attendance> attendances = [];

  // do initialize
}

class AttendancesPage extends StatelessWidget {
  final int userId;

  AttendancesPage(this.userId);

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (_) => AttendancesModel(userId),
      child: Consumer(
        builder: (_, model, __) {
          print('model.userId=${model.userId}')
          return Scaffold(
            // appbar, body, etc...
          );
        }
      )
    );
  }
}

但是,构建器收到的模型始终是相同的值。
因此,更改用户选择不会更改详细信息屏幕。
如何创建新模型?

谢谢。

[编辑] 这样的UserListPage会通知用户选择

class UserListModel with ChangeNotifier {
  List<User> users = [];
  int _selectedUserId;
  int get selectedUserId => _selectedUserId;
  set selectedUserId(int userId) {
    _selectedUserId = userId;
    notifyListeners();
  }
}

class UserListPage extends StatelessWidget {

  Widget build(BuildContext context) {
    return ChangeNotifierProvider.value(
      value: Provider.of<UserListModel>(context),
      child: Consumer(
        builder: (_, model, __) {
          return ListView.builder(
            itemBuilder: (_, i) {
              final user = model.users[i];
              return ListTile(
                title: Text(user.name),
                onTap: () => model.selectedUserId = user.id,
              );
            },
            itemCount: model.users.length
          );
        }
      )
    )
  }
}

class HomePage extends StatelessWidget {
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (_) => UserListModel(),
      child: HomePageBody()
    );
  }
}

class HomePageBody extends StatelessWidget {
  Widget build(BuildContext context) {
    return Scaffold(
      body: Row(
        children: <Widget>[
          SizedBox(width: 320, child: UserListPage()),
          ChangeNotifierProvider.value(
            value: Provider.of<UserListModel>(context),
            child: Consumer<UserListModel>(
              builder: (_, model, __) {
                return AttendancePage(model.selectedUserId);
              }
            )
          )
        ]
      )
    )
  }
}

1 个答案:

答案 0 :(得分:0)

在AttendancesPage中,您始终传递相同的用户ID。只是为了理解,您想在与用户ID相关的AttendanceModel上打印一些信息吗?

我做了这个。让我们看看它是否有用。

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

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: HomePage(),
    );
  }
}

class User {
  final int userId;
  final String name;

  User(this.userId, this.name);
}

class Attendance {
  final int attendanceId;
  final int userId;
  final String data;

  Attendance({
    this.attendanceId,
    this.data,
    this.userId,
  });
}

class UserListModel with ChangeNotifier {
  List<User> users = [
    User(15, "Rick"),
    User(14, "Bob"),
    User(12, "Lola"),
  ];
  int _selectedUserId;
  int get selectedUserId => _selectedUserId;

  void changeSelectedUserId(int userId) {
    _selectedUserId = userId;
    print(_selectedUserId);
    notifyListeners();
  }
}

class UserListPage extends StatelessWidget {
  Widget build(BuildContext context) {
    return Consumer<UserListModel>(
      builder: (_, model, __) {
        return ListView.builder(
            itemBuilder: (_, i) {
              final user = model.users[i];
              return ListTile(
                title: Text(user.name),
                onTap: () => model.changeSelectedUserId(user.userId),
              );
            },
            itemCount: model.users.length);
      },
    );
  }
}

class HomePage extends StatelessWidget {
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (_) => UserListModel(),
      child: HomePageBody(),
    );
  }
}

class HomePageBody extends StatelessWidget {
  Widget build(BuildContext context) {
    return Scaffold(
      body: Row(
        children: <Widget>[
          Expanded(child: UserListPage()),
          Consumer<UserListModel>(
            builder: (_, model, __) {
              return Expanded(
                child: ChangeNotifierProvider(
                  create: (_) => AttendancesModel(),
                  child: AttendancesPage(model.selectedUserId),
                ),
              );
            },
          ),
        ],
      ),
    );
  }
}

class AttendancesModel with ChangeNotifier {
  List<Attendance> attendances = [
    Attendance(attendanceId: 1, userId: 12, data: "Attendance1"),
    Attendance(attendanceId: 2, userId: 15, data: "Attendance2"),
    Attendance(attendanceId: 3, userId: 14, data: "Attendance3"),
  ];

  Attendance findByUserId(int userId) {
    return attendances.firstWhere((element) => element.userId == userId);
  }
}

class AttendancesPage extends StatelessWidget {
  final int userId;

  AttendancesPage(this.userId);

  @override
  Widget build(BuildContext context) {
    final attendance =
        Provider.of<AttendancesModel>(context).findByUserId(userId);
    return Scaffold(
      body: Center(
        child: Text(
            "${attendance.attendanceId} - ${attendance.userId} - ${attendance.data}"),
      ),
    );
  }
}