富文本图文混排+评论列表
image.png
image.png
富文本三方库
flutter_widget_from_html: ^0.15.3
fwfh_cached_network_image: ^0.14.3
代码实现
class InappWebPage extends StatefulWidget {
const InappWebPage({super.key});
@override
State<InappWebPage> createState() => _InappWebPageState();
}
class _InappWebPageState extends State<InappWebPage> {
List<String> comments = List.generate(10, (index) => "评论 ${index + 1}");
bool isLoadingMore = false;
@override
Widget build(BuildContext context) {
String htmlData = """
<h1>标题</h1>
<p>这是一些文本内容。</p>
<img src="https://via.placeholder.com/150" alt="示例图片" style="width:100%;height:auto;">
<p>这是更多的文本内容。</p>
<p>德玛西亚永世长存 啊数控刀具阿罗卡假大空大家来看啦大家阿喀琉斯大健康拉屎大家阿斯利康到啦开始假大空老实交代阿里 了;艾迪康撒;离开挨了打撒库拉就打了蛇口街道撒恐龙当家撒恐龙当家啊蓝思科技。</p> <img src="https://img0.baidu.com/it/u=4215965142,3207288481&fm=253&fmt=auto&app=120&f=JPEG?w=889&h=500" alt="示例图片" style="width:100%;height:auto;">
<img src="https://img2.baidu.com/it/u=3553348988,643429383&fm=253&fmt=auto&app=120&f=JPEG?w=607&h=349" alt="示例图片" style="width:100%;height:auto;">
<img src="https://img0.baidu.com/it/u=4215965142,3207288481&fm=253&fmt=auto&app=120&f=JPEG?w=889&h=500" alt="示例图片" style="width:100%;height:auto;">
""";
String aaa = """
<p>英国大学生在美国留学条件,很多同学都很关注这个话题,下面中国教育在线带您深入了解这方面的内容,相信您阅读以下文章后,会得到想要的答案。</p>\n<p><img title=\"英国大学生在美国留学条件\" src=\"https://www.eol.cn/waiyu/upload/images/2023/5/cb7df1dfc5921e96.jpg\" alt=\"英国大学生在美国留学条件\"></p>\n<p>英国留学生可以去美国留学,但需要满足一定的条件。首先,留学生需要获得美国签证,通常是F1学生签证。申请签证时需要提供相关的材料,如录取通知书、财力证明、学历证明等。其次,留学生需要满足美国大学的招生要求,包括英语能力、学术成绩、标准化考试成绩等。最后,留学生需要承担留学费用和生活费用。</p>\n<p><strong>Part1.GPA</strong></p>\n<p>申请学生高中三年的GPA表现了学生在高中阶段的整体学习水平,因此招考官们非常重视,所以准备留学美国的学生,在高一的时候就要努力提高每一门课程的GPA,因为GPA的整体水平能够决定你能申请到怎样的大学。</p>\n<p><strong>Part2.语言成绩</strong></p>\n<p>大家在申请美国大学时首先考的是语言成绩,托福,雅思考试,这是进入美国院校的敲门砖。</p>\n<p>一般在申请美国大学时都需要提供SAT和托福成绩,SAT是标准化考试,类似于我国的高考,托福考试就是针对申请学生的英语能力进行考察,这两项考试很重要,但是考好不容易,因此备考学生要多做托福考试真题,了解托福考试的命题特点以及考点,然后努力拿下它。</p>\n<p><strong>Part3.文书</strong></p>\n<p>文书能够向学校评审委员会展示你的才情,品质与个性。</p>\n<p>申请文书包括个人介绍和推荐信,好的文书会通过一两件事把学生的形象栩栩如生地展现在招生官面前,既考验写作功底,又考验英语水平。</p>\n<p><strong>Part4.适合</strong></p>\n<p>在选择美国大学时,很多申请学生只是一味追求名牌大学,所以定的学校基本上不是藤校就是牛剑,完全忽略了一个要点:自己适不适合这个学校?自己能不能申请到这些大咖学校?</p>\n<p>小编建议,学生在申请学校时,根据自身的情况,做一个比较合理的阶梯,排名前20的选择2所,前50的选择3所,前100的选择2所,这样既有冲刺的名校,也有保底的学校,可以确保自己能够有学上,千万不能把所有的名额都压在前30名校上。</p>\n<p>除了学校的排名,学校的地理位置也要考虑,因为地理位置决定了将来的生活费用,兼职打工的机会,以及毕业后的实习就业问题等等。</p>\n<p><strong>Part5.课外活动</strong></p>\n<p>课外活动追求“质”的提升,而不是追求“量”的积累,参加活动的数量非常多,只会让美国名校觉得你可能是个全面发展的学生,但是不会留下深刻的印象,很难在一大堆的申请材料中脱颖而出。</p>\n<p>如果把一系列的课外活动比作是有大有小的珍珠,我们要做的就是将这些散落的珍珠串成一条美丽的,匀称的项链,而不是大小不一,瑕瑜不明的手串,要对自己参加的活动进行梳理,然后把一两个更能凸显你的特点,优点或者是能力的活动找出来,深入挖掘,而不是把一堆有的没的活动进行堆积。</p>\n<p><strong>Part6.面试</strong></p>\n<p>美国大部分院校,尤其是常春藤学校,虽然已经取消了校内面试,但是还是会进行各种各样的,形形色色的面试来充分了解学生,比如说制作Video,或者是校友面试,毕竟名校毕业生遍布全球,美国招考官可能会委托中国校友对你进行一轮又一轮的面试。</p>\n<p>如果大学向你提供面试的机会,这并不是“可去可不去”,而是一定要去。</p>\n<p>如果不能抓住这个机会,面试院校会获得这样一个信息:你不是真的对这个学校感兴趣。</p>\n<p>如果某些学生曾花时间思考为什么这所学校引起他们,或者为什么他们适合这所学校,他们肯定受到学校的喜爱。你不能在面试时只做机械式的交流,但是也不能让别人听起来感觉你好像没有认真思考过为何要加入这所学校。</p>\n<p><strong>Part7.Waitlist</strong></p>\n<p>Waitlist中文翻译为“等待名单”,进入该名单的同学,既没有被大学明确拒绝,但是也没有决定被接受,只有继续等待几个月才能知道最终结果。</p>
""";
Widget htmlWidget = HtmlWidget(
aaa,
factoryBuilder: () => MyWidgetFactory(),
);
Widget commentListWidget = SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
if (index == comments.length && isLoadingMore) {
return const Padding(
padding: EdgeInsets.all(16.0),
child: CircularProgressIndicator(),
);
} else {
return Padding(
padding: const EdgeInsets.all(5.0),
child: Container(
color: Colors.grey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(comments[index]),
if (index % 2 == 0)
Text('我是Detail-$index'),
if (index % 3 == 0)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: ListView.builder(itemBuilder: (context,index){
return Text('我是子评论:$index');
},
itemCount: 10,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
),
),
],
),
),
);
}
},
childCount: comments.length + (isLoadingMore ? 1 : 0),
),
);
return Scaffold(
appBar: AppBar(
title: const Text('Flutter HTML Demo'),
),
body: CustomScrollView(
slivers: <Widget>[
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: htmlWidget,
),
),
const SliverToBoxAdapter(
child: Divider(thickness: 1, indent: 16, endIndent: 16),
),
commentListWidget,
if (!isLoadingMore)
const SliverToBoxAdapter(
child: Padding(
padding:
EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: ElevatedButton(
onPressed: null,
child: Text('加载更多评论'),
),
),
),
],
),
);
}
}
class MyWidgetFactory extends WidgetFactory with CachedNetworkImageFactory {
@override
Widget? buildImage(BuildTree tree, ImageMetadata data)
{
String? imageUrl;
for (final source in data.sources) {
imageUrl = source.url;
break;
}
if (imageUrl != null) {
return CheckBtn(
onTap: () {
print("url是:$imageUrl");
},
child: Image.network(imageUrl));
}
return null; // 或者 return PlaceholderWidget();
}
}