首页 > 解决方案 > 当 url 值更改时,Flutter Image.Network 不会重建/触发 api 调用

问题描述

标题基本上总结了我遇到的问题。在下面的代码中,您可以看到我为 URL 输入分配了一个文本字段控制器。我希望效果是当用户完成输入 URL 时,图像会自动更新。就我而言,在字段值更改后,图像永远不会更新。但是,一旦执行热重载,图像就会发生变化。只有这样才能达到预期的效果。这里发生了什么?我会假设在每次更改 Text 控制器值时,都会重建整个表单(当我在开发工具中启用彩虹旗时我确实看到了),除了图像小部件。为什么会这样?

import 'dart:math';

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

class EditProductPage extends StatefulWidget {
  static const routeName = '/edit-product-page';
  @override
  _EditProductPageState createState() => _EditProductPageState();
}

class _EditProductPageState extends State<EditProductPage> {
  final _urlTextController = TextEditingController();

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Edit Product'),
      ),
      body: Card(
        elevation: 5,
        child: Padding(
          padding: const EdgeInsets.all(15),
          child: Form(
            child: ListView(
              children: [
                TextFormField(
                  decoration: InputDecoration(labelText: 'Title'),
                  textInputAction: TextInputAction.next,
                ),
                TextFormField(
                  decoration: InputDecoration(labelText: 'Price'),
                  keyboardType: TextInputType.number,
                  textInputAction: TextInputAction.next,
                ),
                TextFormField(
                  decoration: InputDecoration(labelText: 'Description'),
                  maxLines: 3,
                  keyboardType: TextInputType.multiline,
                ),
                Row(
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: <Widget>[
                    Container(
                      width: 100,
                      height: 100,
                      margin: EdgeInsets.only(
                        top: 8,
                        right: 10,
                      ),
                      decoration: BoxDecoration(
                        border: Border.all(
                          width: 1,
                          color: Colors.grey,
                        ),
                      ),
                      child: _urlTextController.text.isEmpty
                          ? Text('Enter a URL')
                          : FittedBox(
                              child: Image.network(
                                _urlTextController.text,
                                fit: BoxFit.cover,
                                key: ValueKey(_urlTextController.text),
                              ),
                            ),
                    ),
                    Expanded(
                      child: TextFormField(
                        decoration: InputDecoration(labelText: 'Image URL'),
                        keyboardType: TextInputType.url,
                        textInputAction: TextInputAction.done,
                        controller: _urlTextController,
                      ),
                    ),
                  ],
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

标签: flutterdart

解决方案


每次用户输入内容以使用新值重建表单时,您都需要更改状态

  @override
  void initState() {
    _urlTextController.addListener(onUrlChanged);
    super.initState();
  }
  
  void onUrlChanged() {
    setState(() {});
  }
  
  @override
  void dispose() {
    _urlTextController.removeListener(onUrlChanged);
    super.dispose();
  }

推荐阅读