【问题标题】:Flutter with provider package UI doesn't Update at the detailpage带有提供程序包 UI 的颤振不会在详细信息页面上更新
【发布时间】:2020-07-07 16:20:06
【问题描述】:

我编写了一个 Flutter 应用程序并使用 providers 包管理我的数据。使用图标按钮,您可以将产品标记为收藏。如果我喜欢一个产品(图标从边框变为实心图标),我的产品项目加载到网格视图中,UI 会更新。但是在显示产品更多详细信息的详细信息页面上,如果我按下按钮,UI 不会更新。

这是产品类别:


class Product with ChangeNotifier {
  final String id;
  final String title;
  final String description;
  final double price;
  final String imageUrl;
  bool isFavorite;

  Product({
    @required this.id,
    @required this.title,
    @required this.description,
    @required this.price,
    @required this.imageUrl,
    this.isFavorite = false,
  });

  void toggleFavoriteStatus() {
    isFavorite = !isFavorite;
    notifyListeners();
  }
}

这是我管理数据的产品类:

import 'package:flutter/material.dart';

import './product.dart';

class Products with ChangeNotifier {
  List<Product> _items = [
    Product(
      id: 'p1',
      title: 'Red Shirt',
      description: 'A red shirt - it is pretty red!',
      price: 29.99,
      imageUrl:
          'https://cdn.pixabay.com/photo/2016/10/02/22/17/red-t-shirt-1710578_1280.jpg',
    ),
    Product(
      id: 'p2',
      title: 'Trousers',
      description: 'A nice pair of trousers.',
      price: 59.99,
      imageUrl:
          'https://upload.wikimedia.org/wikipedia/commons/thumb/e/e8/Trousers%2C_dress_%28AM_1960.022-8%29.jpg/512px-Trousers%2C_dress_%28AM_1960.022-8%29.jpg',
    ),
    Product(
      id: 'p3',
      title: 'Yellow Scarf',
      description: 'Warm and cozy - exactly what you need for the winter.',
      price: 19.99,
      imageUrl:
          'https://live.staticflickr.com/4043/4438260868_cc79b3369d_z.jpg',
    ),
    Product(
      id: 'p4',
      title: 'A Pan',
      description: 'Prepare any meal you want.',
      price: 49.99,
      imageUrl:
          'https://upload.wikimedia.org/wikipedia/commons/thumb/1/14/Cast-Iron-Pan.jpg/1024px-Cast-Iron-Pan.jpg',
    ),
  ];

  List<Product> get items {
    return [..._items];
  }

  Product findById(String id) {
    return _items.firstWhere((prod) => prod.id == id);
  }
}

这是产品项目:

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

import '../screens/product_detail_screen.dart';
import '../providers/product.dart';

class ProductItem extends StatelessWidget {
  // final String id;
  // final String title;
  // final String imageUrl;

  // ProductItem(this.id, this.title, this.imageUrl);

  @override
  Widget build(BuildContext context) {
    final product = Provider.of<Product>(context, listen: false);
    return ClipRRect(
      borderRadius: BorderRadius.circular(10),
      child: GridTile(
        child: GestureDetector(
          onTap: () {
            Navigator.of(context).pushNamed(
              ProductDetailScreen.routeName,
              arguments: product.id,
            );
          },
          child: Image.network(
            product.imageUrl,
            fit: BoxFit.cover,
          ),
        ),
        footer: GridTileBar(
          backgroundColor: Colors.black87,
          leading: Consumer<Product>(
            builder: (ctx, product, child) => IconButton(
                  icon: Icon(
                    product.isFavorite ? Icons.favorite : Icons.favorite_border,
                  ),
                  color: Theme.of(context).accentColor,
                  onPressed: () {
                    product.toggleFavoriteStatus();
                  },
                ),
          ),
          title: Text(
            product.title,
            textAlign: TextAlign.center,
          ),
          trailing: IconButton(
            icon: Icon(
              Icons.shopping_cart,
            ),
            onPressed: () {},
            color: Theme.of(context).accentColor,
          ),
        ),
      ),
    );
  }
}

这是详细页面:

import 'dart:html';

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

import '../providers/products.dart';

class ProductDetailScreen extends StatelessWidget {
  // final String title;
  // final double price;

  // ProductDetailScreen(this.title, this.price);
  static const routeName = '/product-detail';

  @override
  Widget build(BuildContext context) {
    final productId =
        ModalRoute.of(context).settings.arguments as String; // is the id!
    final loadedProduct = Provider.of<Products>(
      context,
      listen: false,
    ).findById(productId);
    return Scaffold(
      appBar: AppBar(
        title: Text(loadedProduct.title),
        actions: <Widget>[
          IconButton(
            onTap: () {
              loadedProduct.toggleFavoriteStatus();
            },
            child: Icon(
              loadedProduct.isFavorite ? Icons.star : Icons.star_border,
              color: Colors.white,
            ),
          ),
        ],
      ),
    );
  }
}

感谢所有试图为此找到解决方案的人。

【问题讨论】:

    标签: flutter dart flutter-provider


    【解决方案1】:

    它不会更新 UI,因为没有 Product 类型的 Provider 或 Consumer 来监听新路由中的这些更改。你有Provider&lt;Products&gt; 并从那里提取一个Product,但就是这样,路由不依赖/监听Product,因为在小部件树的那部分没有Provider&lt;Product&gt;

    我建议将提供者的值公开给新路由,而不是传递 id 并创建新的提供者。

    onTap: () {
      Navigator.of(context).pushNamed(
        ProductDetailScreen.routeName,
        arguments: product, //pass the Product instead of the id
      );
    },
    
    class ProductDetailScreen extends StatelessWidget {
      // final String title;
      // final double price;
    
      // ProductDetailScreen(this.title, this.price);
      static const routeName = '/product-detail';
    
      @override
      Widget build(BuildContext context) {
        return ChangeNotifierProvier<Product>.value(
           value: ModalRoute.of(context).settings.arguments as Product
           child: Consumer<Product>(
             builder: (context, loadedProduct, _){
               return Scaffold(
                 appBar: AppBar(
                   title: Text(loadedProduct.title),
                   actions: <Widget>[
                     IconButton(
                       onTap: () {
                         loadedProduct.toggleFavoriteStatus();
                       },
                       child: Icon(
                         loadedProduct.isFavorite ? Icons.star : Icons.star_border,
                         color: Colors.white,
                       ),
                     ),
                   ],
                 ),
               );
             }
           )
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-23
      • 2020-10-22
      • 1970-01-01
      • 2016-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多