Flutter 之新闻详情页一——加载本地动态网页

现在的新闻阅读界面一般都包含两部分,新闻文章内容和用户评论列表。内容一般都是HTML富文本数据,以便实现丰富的展示风格。现在Flutter原生没有支持的HTML富文本展示,也没有提供类似的于WebView的Widget。只能使用插件方式调用原生的WebView。

详情页逻辑流程:

网络请求新闻数据------组装成标准的HTML(一般是静态的)-------浏览器加载页面

我网络请求返回数据组装后的HTML纯文本数据

<html>
  <head>
    <meta name="generator"
    content="HTML Tidy for HTML5 (experimental) for Windows https://github.com/w3c/tidy-html5/tree/c63cc39" />
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
    <link rel="stylesheet" type="text/css" href="main.css" />
    <title></title>
  </head>
  <body>
    <section data-role="outer" label="Powered by 135editor.com" style="font-size: 16px; font-family: 微软雅黑;">
      <section data-role="outer" label="Powered by 135editor.com">
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-indent: 0em; text-align: center;">

          <img imageflag=""
          src="https://cdnproduce.yunshicloud.com/wenshan/QMTNRK_YUNSHI/F41EF6C10FA3408DB377A13D5A01466F/5e7b22b63e73672e423375d50cb694a5.jpg"
          style="width: 100%;" />
        </p>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-align: justify; text-indent: 2em;">

          <span style="font-size: 17px;">连日来,为维护消费者合法权益,保护人民群众猪肉食品安全,文山市市场监督管理局组织执法人员开展辖区内生猪肉市场、酒店餐桌专项检查活动,保障辖区内生猪肉市场的安全。</span>
        </p>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-indent: 0em; text-align: center;">

          <img alt="" height="1080" src="/sites/default/files/news/087659cfb4f94ee074a35c3bcdea9999.jpg" width="1440" />
        </p>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-align: justify; text-indent: 2em;">

          <span style="font-size: 17px;">此次检查的重点是农贸市场和各大酒店宾馆,在诗达酒店,作为一家四星级酒店,餐桌食品安全备受关注,检查人员先后检查了该酒店的生产操作间、储存仓库及各类食品进货台账,摸清了猪肉进货渠道和销售数量,并结合《食品安全法》《生猪屠宰管理条例》等相关法律法规,进一步加强宣传,引导广大经营业者守法经营。督促其建立健全进销货台账、进货检验、索证索票、质量承诺,落实猪肉来源溯源制度,保证猪肉合格,同时和酒店签订了文山市餐饮行业非洲猪瘟防控工作承诺书。</span>
        </p>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-indent: 0em; text-align: center;">
        </p>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-indent: 0em; text-align: center;">

          <span style="font-size: 17px;">
          <img imageflag=""
          src="https://cdnproduce.yunshicloud.com/wenshan/QMTNRK_YUNSHI/F41EF6C10FA3408DB377A13D5A01466F/92fe6ad88b8b78efc8af05fe1b4d48c1.jpg"
          style="width: 100%;" /> 
          <img imageflag=""
          src="https://cdnproduce.yunshicloud.com/wenshan/QMTNRK_YUNSHI/F41EF6C10FA3408DB377A13D5A01466F/3eca8da600b80b9b45db45e3d2c46146.jpg"
          style="text-indent: 0em; caret-color: red; width: 100%;" /> </span>
        </p>
        <section class="_135editor" data-id="88403" data-tools="135编辑器" style="border: 0px none; box-sizing: border-box;">
          <section>
            <section style="margin-top: 0.5em; margin-bottom: 0.5em; position: static;">
              <section style="border-top: 3px dashed rgb(147, 122, 122); box-sizing: border-box;"></section>
            </section>
            <section style="margin-top: 20px; margin-bottom: 20px; position: static;">
              <p style="margin-top: 5px; margin-bottom: 5px; font-size: 15px; line-height: 1.75em; font-family: Arial, sans-serif; color: rgb(120, 114, 114); text-align: justify; text-indent: 2em;">
              <strong>
                <span style="font-size: 17px;">文山诗达酒店 营运总监 罗桂星:</span>
              </strong> 
              <span style="font-size: 17px;">“我们酒店食品安全这一块也是经常有计划有步骤的进行计划性的培训。除此之外,我们餐饮部门之间也会经常在班天会上进行培训,特别是对于我们产品的进入,也是控制得很严。我们专门的采购部门,对食品的采购进行整个流程的一个控制。从采买的索证索票以及到我们酒店大门的运货口,我们验收的每一个环节,也是严控,还有我们的成品与半成品都会分开管理和分开储存。”</span></p>
              <p style="margin-top: 5px; margin-bottom: 5px; font-size: 15px; line-height: 1.75em; font-family: Arial, sans-serif; color: rgb(120, 114, 114); text-indent: 0em; text-align: center;">

                <span style="font-size: 17px;">
                  <img imageflag=""
                  src="https://cdnproduce.yunshicloud.com/wenshan/QMTNRK_YUNSHI/F41EF6C10FA3408DB377A13D5A01466F/4fdd642bb1e1abc5dfdcb3b95ba54207.jpg"
                  style="width: 100%;" />
                </span>
              </p>
            </section>
            <section style="margin-top: 0.5em; margin-bottom: 0.5em; position: static;">
              <section style="border-top: 5px dashed rgb(147, 122, 122); box-sizing: border-box;"></section>
            </section>
          </section>
        </section>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-align: justify; text-indent: 2em;">
        </p>
        <section class="_135editor" data-id="89227" data-tools="135编辑器" style="border: 0px none; box-sizing: border-box;">
          <section data-width="100%"
          style="margin: 10px auto; width: 100%; background-color: rgb(251, 251, 251); border-bottom: 1px solid rgb(246, 246, 246); overflow: hidden; box-sizing: border-box;">

            <section style="display: inline-block; width: auto; background-color: rgb(255, 166, 0); border-radius: 0px 0px 10px; margin-right: 60px; margin-left: -30px; padding-left: 30px;transform: skew(-30deg);-webkit-transform: skew(-30deg);-moz-transform: skew(-30deg);-o-transform: skew(-30deg);">

              <section class="135brush" data-brushtype="text"
              style="padding: 8px 30px 8px 20px; color: rgb(255, 255, 255);transform: skew(30deg);-webkit-transform: skew(30deg);-moz-transform: skew(30deg);-o-transform: skew(30deg);">

                <strong>
                  <span style="font-size: 17px;">采访中,酒店还承诺:</span>
                </strong>
              </section>
            </section>
          </section>
        </section>
        <section class="_135editor" data-id="91614" data-tools="135编辑器" style="border: 0px none; box-sizing: border-box;">
          <section class="_135editor" style="border: 0px none; box-sizing: border-box;">
            <section style="padding: 10px; box-sizing: border-box;">
              <section style="color: rgb(133, 133, 133); line-height: 30px; border: 2px solid rgb(136, 136, 136); box-sizing: border-box;">

                <section style="display: -webkit-flex; justify-content: center; align-items: center;">
                  <section class="135brush" data-brushtype="text" data-width="65%"
                  style="width: 65%; line-height: 30px; font-size: 22px; color: rgb(220, 54, 74); padding-left: 10px; box-sizing: border-box;">
                  </section>
                  <section data-width="35%" style="width: 35%;">
                    <section style="width: 115px; float: right; margin-right: -4px; margin-top: -23px;"></section>
                  </section>
                </section>
                <section class="135brush"
                style="padding-right: 15px; padding-bottom: 30px; padding-left: 15px; text-align: justify; box-sizing: border-box;">

                  <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-indent: 2em;">

                    <span style="font-size: 17px;">一、严格按照云南省非洲猪瘟防控工作会议要求,不使用餐厨剩余物、废弃物(潲水)饲喂生猪,不向生猪养猪场和养猪户出售餐厨剩余物、废弃物(潲水)。</span>
                  </p>
                  <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-indent: 2em;">

                    <span style="font-size: 17px;">二、采购猪肉向供货方索取《生猪检验检疫合格证明》,坚决不购买未经检验检疫的猪肉。</span>
                  </p>
                  <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-indent: 2em;">

                    <span style="font-size: 17px;">三、保持食品加工、经营场所内外的卫生清洁,确保无卫生死角,无蟑螂、老鼠、苍蝇。</span>
                  </p>
                  <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-indent: 2em;">

                    <span style="font-size: 17px;">四、认真履行食品安全主任责任,严把食品安全质量关。</span>
                  </p>
                </section>
                <section data-width="100%" style="width: 100%;">
                  <section style="width: 80px; height: 15px; float: right; border-bottom: 2px solid rgb(136, 136, 136); border-right: 2px solid rgb(136, 136, 136); margin-top: -19px; margin-right: 4px; box-sizing: border-box;">
                  </section>
                </section>
              </section>
            </section>
          </section>
        </section>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-align: justify; text-indent: 2em;">

          <span style="font-size: 17px;">在文山城区文新农贸市场,检查人员详细询问经营户生猪肉来源,检查是否具有相关对应的票据,所售猪肉是否经过卫生部门检疫。严禁露天经营,确保猪肉市场消费安全。并要求经营者在销售过程中做好防鼠防蝇措施,让消费者放心吃肉,吃到放心肉。</span>
        </p>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-indent: 0em; text-align: center;">

          <span style="font-size: 17px;">
            <img imageflag=""
            src="https://cdnproduce.yunshicloud.com/wenshan/QMTNRK_YUNSHI/F41EF6C10FA3408DB377A13D5A01466F/bd3b9a79d4cfb19cea065a0dd9ef5acf.jpg"
            style="width: 100%;" />
          </span>
        </p>
        <section class="_135editor" data-id="88403" data-tools="135编辑器" style="border: 0px none; box-sizing: border-box;">
          <section>
            <section style="margin-top: 0.5em; margin-bottom: 0.5em; position: static;">
              <section style="border-top: 3px dashed rgb(147, 122, 122); box-sizing: border-box;"></section>
            </section>
            <section style="margin-top: 20px; margin-bottom: 20px; position: static;">
              <p style="margin-top: 5px; margin-bottom: 5px; font-size: 15px; line-height: 1.75em; font-family: Arial, sans-serif; color: rgb(120, 114, 114); text-align: justify; text-indent: 2em;">
              <strong>
                <span style="font-size: 17px;">市民:</span>
              </strong> 
              <span style="font-size: 17px;">“我们买菜一般还是喜欢来市场买,都不喜欢在外面买,怕买到不好的。”</span></p>
              <p style="margin-top: 5px; margin-bottom: 5px; font-size: 15px; line-height: 1.75em; font-family: Arial, sans-serif; color: rgb(120, 114, 114); text-indent: 0em; text-align: center;">

                <span style="font-size: 17px;">
                  <img imageflag=""
                  src="https://cdnproduce.yunshicloud.com/wenshan/QMTNRK_YUNSHI/F41EF6C10FA3408DB377A13D5A01466F/cfb5635f567d5154324a55aa9a38d868.jpg"
                  style="width: 100%;" />
                </span>
              </p>
            </section>
            <section style="margin-top: 0.5em; margin-bottom: 0.5em; position: static;">
              <section style="border-top: 5px dashed rgb(147, 122, 122); box-sizing: border-box;"></section>
            </section>
          </section>
        </section>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-indent: 2em; text-align: justify;">

          <span style="font-size: 17px; text-indent: 2em; caret-color: red;">在检查过程中,执法人员不仅向生猪肉经营者、酒店管理者开展了食品安全法律法规宣传,引导经营者增强主体责任意识,从自我做起。同时向周边消费者宣传食品安全法,告知消费者购买生猪肉时要检查猪肉是否盖有防疫部门的检疫章,出现问题及时向食品药品监管部门反映,共同维护生猪肉消费市场,维护人民群众舌尖上的安全。检查当天未发现不合格猪肉以及其他问题。</span>
        </p>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-align: justify; text-indent: 2em;">
        </p>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-align: justify; text-indent: 2em;">

          <span style="font-size: 17px;">本台:周 秋 张 麟 实习:杨仁洁</span>
        </p>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-align: justify; text-indent: 2em;">

          <span style="font-size: 17px;">编辑:张海蓝 刘虹</span>
        </p>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-align: justify; text-indent: 2em;">

          <span style="font-size: 17px;">制作:冯明兰 农锦庄</span>
        </p>
        <p style="margin-top: 5px; margin-bottom: 5px; line-height: 1.75em; font-family: Arial, sans-serif; text-align: justify; text-indent: 2em;">

          <span style="font-size: 17px;">责任编辑:胡润</span>
        </p>
      </section>
    </section>
  </body>
</html>

详情页网页加载:

  • 想法1:
    Dart可以开发web开发,把组装的静态HTML标签转换成Flutter的对应的Widget(翻译一遍)
    当前也有一些现成的库:例如:flutter_html;flutter_widget_from_html_core
    我均尝试使用了一番,发现对于style和背景较多的网页不能美观的展示。

优点是全程可控,绕开了WebView加载时的滑动冲突,但缺点也十分明显,工作量大(就像自己实现了一个浏览器,兼容性还十分不好的浏览器),展示的页面效果没有WebView效果好。

  • 想法2:使用浏览器加载,使用原生WebView加载网页。现在也有较好的WebView插件。主要尝试用了一下flutter_webview_plugin和flutter_inappbrowser;
    flutter_webview_plugin: 主要用来打开网站,非常方便,但需要指定相对于屏幕的固定的显示区域。Rect。而在开发的时候往往不好计算得到十分精确的区域。
    flutter_inappbrowser:应该算着flutter_webview_plugin的改进版。 支持内嵌入页面。也需要固定的widget宽高。

由于客户要求比较高,和大量的兼容性考虑,还是决定WebView加载网页。当前的WebView插件都是使用HTML的URL方式加载网页。因此我们还需要把数据保存为文件,在使用WebView去加载本地网页。

流程变更为:
网络请求新闻数据------组装成标准的HTML(一般是静态的)------- 写入本地设备html(包括通用的css 文件和 html文件)----- WebView加载html

文件读写

1.保存的文件的位置,使用path_provider插件,可以实现跨平台文件路劲的获取。

  Future<File> _getLocalCssFile() async {
// 获取本地文档目录
    String dir = (await getApplicationDocumentsDirectory()).path;
// 返回本地文件目录
    return new File('$dir/$fileCssName');
  }

  Future<File> _getLocalHtmlFile() async {
// 获取本地文档目录
    String dir = (await getApplicationDocumentsDirectory()).path;
// 返回本地文件目录
    return new File('$dir/$fileName');
  }

2.写入文件
先写入通用的CSS文件,通用的Css源文件使用assets方式存放。当时苦于不知道flutter怎么获取asset的URI地址。因此又使用IO操作重新另存一遍。
assets配置

  assets:
    - htmlsource/css/main.css

另存为代码:(注意:这里进行了防止重复IO操作代码,但要注意排除修改css文件内容情况,当前没有实现这个升级修改Css内容的维护)

void _checkCssFile() async {
    File file = await _getLocalCssFile();
    bool isExist = await file.exists();
    int fileLength = isExist ? await file.length() : -1;
    print('csss file length === $fileLength');
    if (!isExist || fileLength <= 0) {
      if (isExist) {
        await file.delete();
      }
      await file.create();
      String cssStr = await DefaultAssetBundle.of(context)
          .loadString('htmlsource/css/main.css');
      print('csss ==== $cssStr');
      await file.writeAsString(cssStr);
    }
  }

写入Html文件:并使用URL更新WebView

void _writeDataFile(String data) async {
    _checkCssFile();
    File file = await _getLocalHtmlFile();
    File afterFile = await file.writeAsString(data);
    setState(() {
      _webUrl = afterFile.uri.toString();
    });
    print('weburl ==== $_webUrl');
  }

加载HTML完整代码:

import 'dart:io';

import 'package:demonewsapp/page/native_web_view.dart';
import 'package:demonewsapp/page/webview.dart';
import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:html/dom.dart' as dom;
import 'package:html/parser.dart' as html;
import 'package:path_provider/path_provider.dart';

class NewsDetailsWeb extends StatefulWidget {
  String body;
  List<Widget> widgets;

  NewsDetailsWeb(
      {Key key, @required String this.body, List<Widget> this.widgets})
      : super(key: key);

  @override
  NewsDetailsWebState createState() {
    return NewsDetailsWebState();
  }
}

class NewsDetailsWebState extends State<NewsDetailsWeb> {
  final String fileName = 'wenshan_details.html';
  final String fileCssName = 'wenshan_details_css.css';
  String _webUrl = '';
  double top = 156.899;

  @override
  void initState() {
    super.initState();
    _createHtmlContent();
  }

  void _createHtmlContent() async {
    String cssUrl = (await _getLocalCssFile()).uri.toString();
    String cssHead =
        '''<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"/>
    <link rel="stylesheet" type="text/css" href="${cssUrl}" />''';
    String newHtml = cssHead + widget.body;
    dom.Document doc = html.parse(newHtml);
    String htmlContent = doc.outerHtml;
    print('htmlContent === $htmlContent');
    _writeDataFile(htmlContent);
  }

  void _checkCssFile() async {
    File file = await _getLocalCssFile();
    bool isExist = await file.exists();
    int fileLength = isExist ? await file.length() : -1;
    print('csss file length === $fileLength');
    if (!isExist || fileLength <= 0) {
      if (isExist) {
        await file.delete();
      }
      await file.create();
      String cssStr = await DefaultAssetBundle.of(context)
          .loadString('htmlsource/css/main.css');
      print('csss ==== $cssStr');
      await file.writeAsString(cssStr);
    }
  }

  void _writeDataFile(String data) async {
    _checkCssFile();
    File file = await _getLocalHtmlFile();
    File afterFile = await file.writeAsString(data);
    setState(() {
      _webUrl = afterFile.uri.toString();
    });
    print('weburl ==== $_webUrl');
  }

  Future<File> _getLocalCssFile() async {
// 获取本地文档目录
    String dir = (await getApplicationDocumentsDirectory()).path;
// 返回本地文件目录
    return new File('$dir/$fileCssName');
  }

  Future<File> _getLocalHtmlFile() async {
// 获取本地文档目录
    String dir = (await getApplicationDocumentsDirectory()).path;
// 返回本地文件目录
    return new File('$dir/$fileName');
  }

  @override
  Widget build(BuildContext context) {
    return getNativeWeb();
  }

  Widget getNativeWeb() {
    return _webUrl.isNotEmpty
        ? NativeWebView(
            webUrl: _webUrl,
            webRect: Rect.fromLTWH(0.0, 0.0, MediaQuery.of(context).size.width,
                MediaQuery.of(context).size.height - AppBar().preferredSize.height
                    -MediaQuery.of(context).padding.top),
          )
        : new Container(
            height: 300.0,
            color: Colors.yellow,
          );
  }

  Widget getRectSizeWeb() {
    return _webUrl.isNotEmpty
        ? new WebViewWidget(
            url: _webUrl,
            webRect: Rect.fromLTWH(0.0, top, MediaQuery.of(context).size.width,
                MediaQuery.of(context).size.height - top),
            withZoom: false,
            withLocalStorage: true,
            scrollBar: false,
          )
        : new Container(
            height: 300.0,
            color: Colors.yellow,
          );
  }

  Widget getHtmlView() {
    return Container(
      child: Html(
        data: widget.body,
        padding: EdgeInsets.all(8.0),
      ),
    );
  }
}

InAppWebView 网页加载的代码:

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

class NativeWebView extends StatelessWidget {
  String webUrl;
  final Rect webRect;
  InAppWebViewController webView;

  NativeWebView({Key key, this.webUrl, this.webRect}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    InAppWebView webWidget = new InAppWebView(
        initialUrl: webUrl,
        initialHeaders: {},
        initialOptions: {},
        onWebViewCreated: (InAppWebViewController controller) {
          webView = controller;
        },
        onLoadStart: (InAppWebViewController controller, String url) {
          print("started -------------- $url");
          this.webUrl = url;
        },
        onProgressChanged: (InAppWebViewController controller, int progress) {
          double prog = progress / 100;
          print('prog --------- $prog');
        });

    return Container(
      width: webRect.width,
      height: webRect.height,
      child: webWidget,
    );
  }
}

效果:


example1.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容