简体   繁体   English

如何在 Flutter 中重新格式化来自 Blogger API 的数据

[英]How to reformat the data from Blogger API in Flutter

I'm creating an app for my new blog, which is hosted on blogger.com.我正在为我的新博客创建一个应用程序,该应用程序托管在 blogger.com 上。 I've got the posts to get displayed in the app along with the images, but for some reason I can't get the text in the post to be formatted.我已经将帖子与图像一起显示在应用程序中,但由于某种原因,我无法设置帖子中的文本格式。 It has just bunched it all together.它只是将它们组合在一起。

Here's how it looks in the blog & in the app:这是它在博客和应用程序中的外观: 在此处输入图片说明

How can I format this in my code so that it looks like it does in the blog?如何在我的代码中格式化它,使其看起来像在博客中一样?

Here's the code I'm using in the main.dart file:这是我在 main.dart 文件中使用的代码:

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:html/parser.dart';
import 'pages/post_view.dart';

void main() => runApp(new MyApp());

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

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  var _isLoading = true; //For progress bar
  var posts;
  var imgUrl;
  //initialization
  void initState() {
    super.initState();
    _fetchData();
  }
  //Function to fetch data from JSON
  @override
  _fetchData() async {
    print("attempting");
    final url =
        "https://www.googleapis.com/blogger/v3/blogs/8902712678213444829/posts/?key=AIzaSyDpwI-kMZ_IxqAJVBKAVtWLOlaGQ5YLEuw";
    final response = await http.get(url);
    print(response.body);
    if (response.statusCode == 200) { 
      //HTTP OK is 200
      final Map items = json.decode(response.body);
      var post = items['items'];

      setState(() {
        _isLoading = false;
        this.posts = post;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text("Blogger"),
          actions: <Widget>[
            new IconButton(
                icon: new Icon(Icons.refresh),
                onPressed: () {
                  setState(() {
                    _isLoading = true;
                  });
                  _fetchData();
                })
          ],
        ),
        body: new Center(
            child: _isLoading
                ? new CircularProgressIndicator()
                : new ListView.builder(
                    itemCount: this.posts != null ? this.posts.length : 0,
                    itemBuilder: (context, i) {
                      final post = this.posts[i];
                      final postDesc = post["content"];
                      //All the below code is to fetch the image
                      var document = parse(postDesc);
                      //Regular expression
                      RegExp regExp = new RegExp(
                        r"(https?:\/\/.*\.(?:png|jpg|gif))",
                        caseSensitive: false,
                        multiLine: false,
                      );
                      final match = regExp
                          .stringMatch(document.outerHtml.toString())
                          .toString();
                      //print(document.outerHtml);
                      //print("firstMatch : " + match);
                      //Converting the regex output to image (Slashing) , since the output from regex was not perfect for me
                      if (match.length > 5) {
                        if (match.contains(".jpg")) {
                          imgUrl = match.substring(0, match.indexOf(".jpg"));
                          print(imgUrl);
                        } else {
                          imgUrl =
                              "https://www.googleapis.com/blogger/v3/blogs/8902712678213444829/posts/?key=AIzaSyDpwI-kMZ_IxqAJVBKAVtWLOlaGQ5YLEuw";
                        }
                      }
                      String description = document.body.text.trim();
                      //print(description);

                      return new Container(
                        padding:
                            const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 8.0),
                        child: new Column(
                          mainAxisAlignment: MainAxisAlignment.spaceAround,
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: <Widget>[
                            new Container(
                              width: 500.0,
                              height: 180.0,
                              decoration: new BoxDecoration(
                                shape: BoxShape.rectangle,
                                image: new DecorationImage(
                                    fit: BoxFit.fitHeight,
                                    //check if the image is not null (length > 5) only then check imgUrl else display default img
                                    image: new NetworkImage(imgUrl
                                                .toString()
                                                .length >
                                            10
                                        ? imgUrl.toString()
                                        : "https://www.googleapis.com/blogger/v3/blogs/8902712678213444829/posts/?key=AIzaSyDpwI-kMZ_IxqAJVBKAVtWLOlaGQ5YLEuw")),
                              ),
                            ),
                            new Padding(
                              padding:
                                  const EdgeInsets.symmetric(vertical: 10.0),
                              child: new Text(
                                post["title"],
                                maxLines: 3,
                                style: new TextStyle(
                                  fontSize: 18.0,
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                            ),
                            new Text(
                              description.replaceAll("\n", ", "),
                              maxLines: 2,
                              overflow: TextOverflow.ellipsis,
                              style: new TextStyle(fontSize: 15.0),
                            ),
                            new Padding(
                              padding:
                                  const EdgeInsets.symmetric(vertical: 16.0),
                              child: new RaisedButton(
                                child: new Text("READ MORE",style: new TextStyle(color: Colors.white),),
                                color: Colors.blue,
                                onPressed: () {
                                  //We will pass description to postview through an argument
                                  Navigator
                                      .of(context)
                                      .push(new MaterialPageRoute<Null>(
                                    builder: (BuildContext context) {
                                      return PostView(post['title'],description,imgUrl);
                                    },
                                  ));
                                },
                              ),
                            ),
                            Divider(),
                          ],
                        ),
                      );
                    },
                  )));
  }
}

And here's the code I'm using in the post_view.dart file:这是我在 post_view.dart 文件中使用的代码:

import 'package:flutter/material.dart';

class PostView extends StatelessWidget {
  var desc, title, image;

  PostView(String title, String desc, String image) {
    this.desc = desc;
    this.title = title;
    this.image = image;
  }
  @override
  Widget build(BuildContext context) {
    if (desc.toString().contains("\n\n\n\n")) {
      desc = desc.toString().replaceAll("\n\n\n\n", "\n\n");
    }

    if (desc.toString().contains("\n\n\n")) {
      desc = desc.toString().replaceAll("\n\n\n", "\n");
    }
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Blogger"),
      ),
      body: new Container(
          child: new SingleChildScrollView(
              child: new Column(
        children: <Widget>[
          new Padding(
            padding:
                const EdgeInsets.symmetric(vertical: 16.0, horizontal: 16.0),
            child: new Text(
              title,
              style: new TextStyle(
                fontSize: 22.0,
                fontWeight: FontWeight.bold,
              ),
            ),
          ),
          new Padding(
            padding:
                const EdgeInsets.symmetric(vertical: 16.0, horizontal: 16.0),
            child: new Container(
              width: 500.0,
              height: 180.0,
              decoration: new BoxDecoration(
                shape: BoxShape.rectangle,
                image: new DecorationImage(
                    fit: BoxFit.fill,
                    //check if the image is not null (length > 5) only then check imgUrl else display default img
                    image: new NetworkImage(image.toString().length > 10
                        ? image.toString()
                        : "https://www.googleapis.com/blogger/v3/blogs/8902712678213444829/posts/?key=AIzaSyDpwI-kMZ_IxqAJVBKAVtWLOlaGQ5YLEuw")),
              ),
            ),
          ),
          new Padding(
            padding:
                const EdgeInsets.symmetric(vertical: 16.0, horizontal: 16.0),
            child: new Text(
              desc,
              style: new TextStyle(
                fontSize: 18.0,
              ),
            ),
          ),
        ],
      ))),
    );
  }
}

EDITED: Here's what get's printed in the console when I hot reload the app:编辑:这是我热重载应用程序时在控制台中打印的内容:

I/flutter ( 9778): attempting
I/flutter ( 9778): {
I/flutter ( 9778):   "kind": "blogger#postList",
I/flutter ( 9778):   "items": [
I/flutter ( 9778):     {
I/flutter ( 9778):       "kind": "blogger#post",
I/flutter ( 9778):       "id": "3086822326789809431",
I/flutter ( 9778):       "blog": {
I/flutter ( 9778):         "id": "8902712678213444829"
I/flutter ( 9778):       },
I/flutter ( 9778):       "published": "2020-06-15T00:22:00-07:00",
I/flutter ( 9778):       "updated": "2020-06-15T22:19:56-07:00",
I/flutter ( 9778):       "url": "http://lessmeatapp.blogspot.com/2020/06/mushroom-tagine.html",
I/flutter ( 9778):       "selfLink": "https://www.googleapis.com/blogger/v3/blogs/8902712678213444829/posts/3086822326789809431",
I/flutter ( 9778):       "title": "Dummy Post 3",
I/flutter ( 9778):       "content": "\u003cbr /\u003e\u003cdiv class=\"separator\" style=\"clear: both; text-align: center;\"\u003e\u003ca href=\"https://1.bp.blogspot.com/-Vv9KcxNHxhU/XuhVnskHvCI/AAAAAAAAAGw/z7tH271PrIEvkQam74G497Gw4A-eFondACK4BGAsYHg/s1400/DD-Grunge-United-Kingdom-Flag-88837-Preview.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"\u003e\u003cimg border=\"0\" data-original-height=\"980\" data-original-width=\"1400\" src=\"https://1.bp.blogspot.com/-Vv9KcxNHxhU/XuhVnskHvCI/AAAAAAAAAGw/z7tH271PrIEvkQam74G497G
I/flutter ( 9778): https://1.bp.blogspot.com/-Vv9KcxNHxhU/XuhVnskHvCI/AAAAAAAAAGw/z7tH271PrIEvkQam74G497Gw4A-eFondACK4BGAsYHg/s1400/DD-Grunge-United-Kingdom-Flag-88837-Preview
I/flutter ( 9778): https://1.bp.blogspot.com/-hvzDDsO44FI/XuhWvqDjRwI/AAAAAAAAAHI/mBjWane0s5wtdJnkLDrNrmyprVoNeWDagCK4BGAsYHg/s1400/DD-Patriotic-Retro-Background-33092-Preview
I/flutter ( 9778): https://1.bp.blogspot.com/-efv2-Ikiyr8/XuhX-YLtDDI/AAAAAAAAAH0/JJE2mrOU-HMsq6Adu1whv5b3W10yqkRlQCK4BGAsYHg/s1400/20


in response, content section is HTML作为回应, content部分是 HTML

and for render HTML in the flutter, you should use fultter_html package并且为了在 flutter 中渲染 HTML,你应该使用fultter_html

you can find it in this link你可以在这个链接中找到它

and with this, you don't need export images from your content有了这个,你不需要从你的内容中导出图像

if you have any question ask me in comments如果您有任何问题,请在评论中问我

in your PostView build method pass description variable to HTML widget:在您的PostView构建方法中,将描述变量传递给 HTML 小部件:

Html(
      data: description,
      //Optional parameters:
      backgroundColor: Colors.white70,

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM