Flutter Bloc Pattern Stream(Flatter Bloc码型流)在导航到另一个屏幕并向后按

时间:2019-03-25 21:33:14

标签: flutter rxdart bloc

我正在创建一个从WordPress其余Api获取帖子的Flutter应用程序,我在MaterialPageRoute内调用获取帖子,当我导航到详细信息屏幕并返回到帖子列表页面时,出现了我的问题,流得到了清除,并在我调用sink.add时替换为新内容,预期的行为是向信息流中添加新帖子。

  

集团

import 'package:app/src/resources/repository.dart';
import 'package:rxdart/rxdart.dart';
import 'package:flutter_wordpress/flutter_wordpress.dart' as wp;

class PostsBloc {
  final Repository _repository = Repository();
  // Also tried PublishSubject
  final _posts = BehaviorSubject<List<wp.Post>>();
  int page = 1;

  // Getters to Streams
  Observable<List<wp.Post>> get posts => _posts.stream;

  fetchMorePosts() async {
    final posts = await _repository.fetchMorePosts(page);
    _posts.sink.add(posts);
    page ++; //Temporary, this will be replaced with load more
  }

  dispose() {
    _posts.close();
  }
}
  

提供商

import 'package:flutter/material.dart';
import 'package:app/src/blocs/post_bloc.dart';
export 'package:app/src/blocs/post_bloc.dart';

class PostsProvider extends InheritedWidget {
  final PostsBloc bloc;

  PostsProvider({Key key, Widget child})
      : bloc = PostsBloc(),
        super(key: key, child: child);

  @override
  bool updateShouldNotify(InheritedWidget oldWidget) {
    return true;
  }

  static PostsBloc of(BuildContext context) {
    return (context.inheritFromWidgetOfExactType(PostsProvider)
            as PostsProvider)
        .bloc;
  }
}
  

主要

import 'package:flutter/material.dart';
import 'package:app/src/app.dart';

void main() => runApp(App());
  

应用

import 'package:flutter/material.dart';
import 'package:app/src/screens/web_view.dart';

import 'package:app/src/blocs/posts_provider.dart';
import 'package:app/src/screens/post_list.dart';
import 'package:app/src/widgets/post_details.dart';

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return PostsProvider(
      child: MaterialApp(
        theme: ThemeData(
          // adding a theme
          brightness: Brightness.dark, //changing the theme to dark
          primaryColor: Colors.black, // color change for links
          accentColor: Colors.green[800], // i dont know
        ),
        title: 'App Title',
        onGenerateRoute: buildRoutes,
      ),
    );
  }

  Route buildRoutes(RouteSettings settings) {
    if (settings.name == '/') {
      return MaterialPageRoute(
        builder: (context) {
          final storiesBloc = PostsProvider.of(context);
          storiesBloc.fetchMorePosts();
          return PostList();
        },
      );
    } else if (settings.name == '/url') {
      return MaterialPageRoute(builder: (context) {
        return WebViewScreen(url: settings.arguments);
      });
    }

    return MaterialPageRoute(builder: (context) {
      return PostDetails(post: settings.arguments);
    });
  }
}
  

帖子列表

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:app/src/blocs/posts_provider.dart';
import 'package:flutter_wordpress/flutter_wordpress.dart' as wp;

class PostList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final bloc = PostsProvider.of(context);
    //print('im called');
    return Scaffold(
      appBar: AppBar(
        title: Text('Latest Posts'),
      ),
      body: _buildPostList(bloc),
    );
  }

  Widget _buildPostList(PostsBloc bloc) {
    return StreamBuilder(
      stream: bloc.posts,
      //initialData: initialData ,
      builder: (BuildContext context, AsyncSnapshot<List<wp.Post>> snapshot) {
        if (!snapshot.hasData) {
          return Center(
            child: CircularProgressIndicator(),
          );
        }
        return ListView.builder(
          itemCount: snapshot.data.length,
          itemBuilder: (BuildContext context, int index) {
            return _buildPostCard(context, post: snapshot.data[index]);
          },
        );
      },
    );
  }

  Widget _buildPostCard(BuildContext context, {wp.Post post}) {
    String title = post.title.rendered;
    wp.Media featuredMedia = post.featuredMedia;
    var id = post.id;
    String date = post.date;
    return /*Hero(
      tag: 'hero$id',
      child:*/
        Container(
      margin: EdgeInsets.all(3),
      height: 200,
      child: InkWell(
        onTap: () =>
            {Navigator.pushNamed(context, '/post/$id', arguments: post)},
        child: Card(
            color: Colors.white,
            shape:
                RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
            child: ClipRRect(
              borderRadius: BorderRadius.circular(20),
              child: Container(
                padding: EdgeInsets.all(14),
                decoration: BoxDecoration(
                  image: DecorationImage(
                      colorFilter: ColorFilter.mode(
                          Colors.black54.withOpacity(0.5), BlendMode.hardLight),
                      fit: BoxFit.cover,
                      // image: NetworkImage(featuredMedia.sourceUrl)),
                      image: CachedNetworkImageProvider(featuredMedia.sourceUrl)),
                  // ),
                  //,
                ),
                child: _columnWithContent(title, date),
              ),
            )),
      ),
      // ),
    );
  }

  _columnWithContent(String title, String date) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.spaceAround,
      children: <Widget>[
        _headerItemBuild(title),
        _dateItemBuild(date),
      ],
    );
  }

  _headerItemBuild(String title) {
    return Row(
      children: <Widget>[
        Flexible(
          child: Column(
            children: <Widget>[
              Text(
                title,
                style: TextStyle(color: Colors.white, fontSize: 18),
              )
            ],
          ),
        ),
        Container(
          child: Row(
            children: <Widget>[
              // IconButton(
              //   icon: Icon(
              //     Icons.share,
              //     color: Theme.of(context).accentColor,
              //   ),
              //   onPressed: () {
              //     //Share.share(widget.model.url);
              //   },
              // ),
              /*IconButton(
                icon: Icon(
                  icons,
                  color: Theme.of(context).accentColor,
                ),
                onPressed: () => _likeUiLogi(),
              ),*/
            ],
          ),
        ),
      ],
    );
  }

  _dateItemBuild(String date) {
    //print(date);
    // Parse date to normal format
    DateFormat format = DateFormat("yyyy-MM-dd'T'HH:mm:ss");
    final unformedDate = format.parse(date);
    Duration difference = unformedDate.difference(DateTime.now());

    return Container(
      padding: EdgeInsets.only(top: 12),
      child: Text(
        (int.tryParse(difference.inHours.abs().toString()) < 12)
            ? difference.inHours.abs().toString() + " hours ago"
            : difference.inDays.abs().toString() + " days ago",
        style: TextStyle(color: Colors.white, fontWeight: FontWeight.w600),
      ),
      alignment: Alignment.centerLeft,
    );
  }
}

// final paddingCardsList = EdgeInsets.symmetric(vertical: 4.0, horizontal: 8.0);
  

帖子详细信息

import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:flutter_wordpress/flutter_wordpress.dart' as wp;
import 'package:cached_network_image/cached_network_image.dart';
import 'package:intl/intl.dart';


class PostDetails extends StatelessWidget {
  final wp.Post post;

  PostDetails({Key key, this.post}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: postTitle(post),
      ),
      body: new Padding(
          padding: EdgeInsets.all(16.0),
          child: new ListView(
            children: <Widget>[
              Column(
                children: <Widget>[
                  //Hero(tag: 'hero${post.id}', child: hawalImage(post)),
                  hawalImage(post),
                  hawalTitle(post),
                  Row(
                    children: <Widget>[
                      Expanded(
                        child: hawalAuthor(post),
                      ),
                      Expanded(
                        child: hawalDate(post),
                      ),
                    ],
                  ),
                  Divider(),
                  contentRendered(context, post),
                ],
              ),
            ],
          )),
    );
  }

  Widget postTitle(wp.Post post) {
    //print(post.title.rendered);
    return Padding(
      padding: EdgeInsets.symmetric(vertical: 10.0),
      child: // Text("data")
          Html(
              data: post.title.rendered,
              defaultTextStyle:
                  TextStyle(fontSize: 20.0, decoration: TextDecoration.none)),
    );
  }

  Widget hawalImage(wp.Post post) {
    return Stack(
      children: <Widget>[
        Positioned(
          bottom: 5.0,
          right: 0,
          left: 0,
          child: Container(
            decoration: BoxDecoration(
              boxShadow: [
                BoxShadow(
                  spreadRadius: 10,
                  blurRadius: 20,
                  color: Colors.black,
                  offset: new Offset(1.0, 1.0),
                ),
              ],
            ),
          ),
        ),
        Container(
          foregroundDecoration: BoxDecoration(
              backgroundBlendMode: BlendMode.overlay,
              gradient: LinearGradient(
                begin: Alignment.topCenter,
                end: Alignment.bottomCenter,
                stops: [0.1, 0.5, 0.7, 0.9],
                colors: [
                  // Colors are easy thanks to Flutter's Colors class.

                  Colors.transparent,
                  Colors.transparent,
                  Colors.black45,
                  Colors.black87,
                ],
              )),
          child: CachedNetworkImage(
//          width: 200.0,
            fadeInCurve: Curves.decelerate,
            repeat: ImageRepeat.noRepeat,
            fadeInDuration: Duration(milliseconds: 500),
            imageUrl: post.featuredMedia.sourceUrl,
            placeholder: (context, url) => new CircularProgressIndicator(),
            errorWidget: (context, url, error) => new Icon(Icons.error),
          ),
        ),
      ],
    );
  }

  Widget hawalBtnBar() {
    return ButtonBar(
      children: <Widget>[
        IconButton(
          icon: Icon(Icons.save),
          splashColor: Colors.blueAccent[200],
          color: Colors.blueGrey,
          tooltip: 'save',
          onPressed: () {
            //debugPrint("save button tapped");
          }, // add +1 to the database
        ),
        IconButton(
          icon: Icon(Icons.favorite),
          splashColor: Colors.redAccent,
          color: Colors.blueGrey,
          tooltip: 'like',
          onPressed: () {
            //debugPrint("favorite button tapped");
          }, // add +1 to the database
        ),
        IconButton(
          icon: Icon(Icons.share),
          color: Colors.blueGrey,
          tooltip: 'share',
          onPressed: () {
            //debugPrint("share button tapped");
          }, // Standard share for whatsapp + google + faccebook + twitter
        ),
      ],
    );
  }

  Widget hawalTitle(wp.Post post) {
    return Padding(
      padding: EdgeInsets.symmetric(vertical: 10.0),
      child: Html(
          data: post.title.rendered,
          defaultTextStyle:
              TextStyle(fontSize: 20.0, decoration: TextDecoration.none)),
    );
  }

  Widget hawalAuthor(wp.Post post) {
    return Text(
      "author: " + post.author.name,
      textAlign: TextAlign.right,
    );
  }

  Widget hawalDate(wp.Post post) {
    return Text(
      dateConvertor(post.date),
      textAlign: TextAlign.left,
    );
  }

  dynamic dateConvertor(String value) {
    //value= "hello";
    String convertedValue;

    convertedValue = DateFormat('y/M/d   H:m').format(DateTime.parse(value));

    return convertedValue;
  }

  Widget contentRendered(BuildContext context, wp.Post post) {
    return Html(
        data: post.content.rendered,
        blockSpacing: 0.0,
        renderNewlines: true,
        useRichText: true,
        onLinkTap: (value) {
         Navigator.pushNamed(context, '/url', arguments: value);
        },
        defaultTextStyle: TextStyle(
          // fontFamily: 'NotoKufiArabic',
          // fontSize: 20.0,
          decoration: TextDecoration.none,
        ));
  }
}

0 个答案:

没有答案