草庐IT

android - Flutter Page 每次在导航弹出时都会重新加载

coder 2023-07-23 原文

我正在构建一个示例应用程序以使用 flutter 框架显示新闻列表。该应用程序有两个页面,一个是主页和详细信息页面。当我从详细页面弹出时,主页每次都会重新加载。

我使用 FutureBuilder 小部件加载新闻并显示为卡片列表,对于详细信息页面,我使用 webview fluggin for flutter 从 url 加载完整新闻。

主页面代码为:

import 'package:flutter/material.dart';
import 'package:flutter_post/detail_page.dart';
import 'package:flutter_post/model/news.dart';
import 'package:flutter_post/services/news_services.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 News',
      debugShowCheckedModeBanner: false,
      theme: new ThemeData(primaryColor: Colors.white, fontFamily: 'Raleway'),
      home: NewsPage(title: 'Flutter News'),
    );
  }
}

class NewsPage extends StatefulWidget {
  NewsPage({Key key, this.title}) : super(key: key);

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

  @override
  _NewsPageState createState() => _NewsPageState();
}

class _NewsPageState extends State<NewsPage> {

  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Align(alignment: Alignment.center, child: Text(widget.title),),
        elevation: 0.1,
        backgroundColor: Colors.white,
      ),
      backgroundColor: Colors.white,
      body: _newsPage(),
    );
  }

  Widget _newsPage() {
    return FutureBuilder<News>(
        future: loadNews(), builder: (context, snapshot) {
      switch (snapshot.connectionState) {
        case ConnectionState.none:
        case ConnectionState.waiting:
          return _loadingRow();
        case ConnectionState.done:
          if (snapshot.hasError) {
            return _errorRow();
          }
          return _newsList(snapshot.data.articles);
        case ConnectionState.active:
      }
    });
  }

  Widget _newsList(List<Article> articles) {
    return ListView.builder(itemCount: articles.length,
        itemBuilder: (BuildContext context, int index) {
          return InkWell(child: Card(
            elevation: 8.0,
            clipBehavior: Clip.antiAlias,
            shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.all(Radius.circular(5.0))),
            margin: EdgeInsets.only(left: 15.0, right: 15.0, bottom: 15.0),
            child: _cardItem(articles[index]),),
            onTap: () {
              Navigator.push(
                  context,
                  MaterialPageRoute(
                      builder: (context) =>
                          DetailPage(article: articles[index],)));
            },);
        });
  }

  Widget _errorRow() {
    return Align(alignment: Alignment.center,
      child: Text(
          "Error!", style: _textStyle(Colors.black38, FontWeight.bold, 20.0)),);
  }

  Widget _cardItem(Article article) {
    return new Container(
      height: 250.0,
      child: new Stack(
        children: <Widget>[
          _cardBackground(article),
          _cardContent(article)
        ],
      ),
    );
  }

  Widget _cardBackground(Article article) {
    return new Container(
      decoration: new BoxDecoration(
        image: new DecorationImage(
            colorFilter: new ColorFilter.mode(
                Colors.black.withOpacity(0.6),
                BlendMode.luminosity),
            image: new NetworkImage(
                article.urlToImage != null ? article.urlToImage : null),
            fit: BoxFit.cover
        ),
      ),
    );
  }

  Widget _cardContent(Article article) {
    return new Align
      (child: Container(
      alignment: Alignment.bottomCenter,
      padding: EdgeInsets.all(10),
      child: new Column(mainAxisAlignment: MainAxisAlignment.end,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Flexible(child: new Text(article.title, maxLines: 2,
              style: _textStyle(Colors.white, FontWeight.bold, 20.0)),),
          Padding(padding: EdgeInsets.only(top: 5.0),),
          Flexible(child: new Text(publishedBy(article),
            style: _textStyle(Colors.white, FontWeight.w400, 12.0),),)
        ],
      ),
    ), alignment: Alignment.bottomLeft,
    );
  }

  String publishedBy(Article article) {
    return "published by " + article.source.name;
  }

  TextStyle _textStyle(Color color, FontWeight weight, double size) {
    return TextStyle(color: color, fontWeight: weight, fontSize: size);
  }

  Widget _loadingRow() {
    return Align(
      alignment: Alignment.center, child: CircularProgressIndicator(),);
  }
}

详细页面代码为:

import 'package:flutter/material.dart';
import 'package:flutter_post/model/news.dart';
import 'package:share/share.dart';
import 'package:webview_flutter/webview_flutter.dart';

class DetailPage extends StatelessWidget {
  final Article article;

  DetailPage({this.article});

  void shareUrl() {
    Share.share('Read the full news from ' + article.url);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: new InkWell(
          onTap: () {
            Navigator.pop(context);
          },
          child: new Icon(Icons.close, color: Colors.black),),
        elevation: 0.1,
        title: new Text(article.url),
        backgroundColor: Colors.white,
      ),
      body: WebView(initialUrl: article.url,),
      floatingActionButton: FloatingActionButton(
        child: new Icon(Icons.share, color: Colors.white),
        onPressed: shareUrl,),
    );
  }
}

我想要的是,每次我从详细信息页面返回时,主页都不应刷新/重新加载。非常感谢任何帮助。

最佳答案

我想我知道你的问题的答案。

  1. _NewsPageState 中创建新闻状态/对象
  2. 使用 initState 加载数据 loadNews()
  3. 在您的 FutureBuilder<News> 中引用 future 对象

示例代码:

class _NewsPageState extends State<NewsPage> {

  Future<News> _myNews;

  @override
  void initState() {
    _myNews = loadNews();
  }

  ...

  Widget _newsPage() {
    return FutureBuilder<News>(
      future: _myNews,
      builder: (context, snapshot) {
        ...
      }
    );
  }

  ...
} 

希望对你有帮助:)

你的 Glup3

关于android - Flutter Page 每次在导航弹出时都会重新加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55683803/

有关android - Flutter Page 每次在导航弹出时都会重新加载的更多相关文章

  1. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  2. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  3. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  4. ruby-on-rails - 每次我尝试部署时,我都会得到 - (gcloud.preview.app.deploy) 错误响应 : [4] DEADLINE_EXCEEDED - 2

    我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie

  5. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  6. ruby-on-rails - 从应用程序中自定义文件夹内的命名空间自动加载 - 2

    我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty

  7. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  8. ruby-on-rails - 使用 gmaps4rails 动态加载谷歌地图标记 - 2

    如何只加载map边界内的标记gmaps4rails?当然,在平移和/或缩放后加载新的。与此直接相关的是,如何获取map的当前边界和缩放级别? 最佳答案 我是这样做的,我只在用户完成平移或缩放后替换标记,如果您需要不同的行为,请使用不同的事件监听器:在你看来(index.html.erb):{"zoom"=>15,"auto_adjust"=>false,"detect_location"=>true,"center_on_user"=>true}},false,true)%>在View的底部添加:functiongmaps4rail

  9. ruby-on-rails - 是否可以让 ActiveRecord 为使用 :joins option? 加载的行创建对象 - 2

    我需要做这样的事情classUser'User',:foreign_key=>'abuser_id'belongs_to:gameendclassGame['JOINabuse_reportsONusers.id=abuse_reports.abuser_id','JOINgamesONgames.id=abuse_reports.game_id'],:group=>'users.id',:select=>'users.*,count(distinctgames.id)ASgame_count,count(abuse_reports.id)asabuse_report_count',:

  10. ruby - 运行 rackup private_pub.ru -s thin -E production 命令时无法加载此类文件 -- thin (LoadError) - 2

    我指的是pubrailscasttutorial并已正确执行所有步骤,但在运行最后一个命令时,即rackupprivate_pub.ru-sthin-Eproduction为了架设faye服务器,我收到以下错误:/usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in`require':cannotloadsuchfile--thin(LoadError)from/usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in`require'from/var/lib/gems/1.9.1/gems

随机推荐