- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
最近,我从事类似项目的画廊工作,该项目显示了数据库中的大量图像。我使用MySQL是因为我拥有专用服务器,并且由于价格原因,使用Firestore可能不是一个好主意。我希望它有一个无限滚动 View ,每次加载10张图像,但是当前它同时加载所有图像,这使应用程序感觉真的很慢。
这是我的lib / main.dart
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:http/http.dart' as http;
//local import, you can ignore it
import './nav.dart';
import './detail.dart';
import './placeholder.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyApp createState() => new _MyApp();
}
class _MyApp extends State<MyApp> {
Future<List> getData() async {
final resp = await http.get("http://192.168.43.68/API/readImage.php");
return json.decode(resp.body);
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return new MaterialApp(
theme: new ThemeData.dark(),
home: Scaffold(
appBar: new AppBar(
title: new Text("Title"),
),
drawer: Nav(),
body: new FutureBuilder(
future: getData(),
builder: (context, snapshot) {
if (snapshot.hasError) {
print(snapshot.error);
}
return snapshot.hasData
? new ItemList(
list: snapshot.data,
)
: new Center(child: new CircularProgressIndicator());
},),),);}}
//Item builder to display each image
class ItemList extends StatelessWidget {
final List list;
ItemList({this.list});
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Padding(
padding: const EdgeInsets.all(0.0),
child: new StaggeredGridView.countBuilder(
crossAxisCount: 4,
itemCount: list.length,
itemBuilder: (BuildContext context, int index) => new Container(
child: new GestureDetector(
onTap: () => Navigator.of(context).push(new MaterialPageRoute(
builder: (BuildContext context) => new Detail(
list: list,
index: index,
))),
child: Card(
child: new Column(
children: <Widget>[
new Stack(
children: <Widget>[
FadeInImage.memoryNetwork(
placeholder: kTransparentImage,
image: list[index]['url'],
),],),
new Padding(
padding: EdgeInsets.all(4.0),
child: new Column(
children: <Widget>[
new Text(list[index]['name'],
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white70,
))],),)],),))),
staggeredTileBuilder: (index) => new StaggeredTile.fit(2),
),);}}
<?php
include 'dbcon.php';
$sth = "SELECT * FROM pict INNER JOIN user ON pict.uid=user.uid LIMIT 10";
$result = $conn->query($sth);
$outp = array();
$outp = $result->fetch_all(MYSQLI_ASSOC);
echo json_encode($outp);
enter code here
最佳答案
我相信您遇到的主要问题是您正在使用StaggeredTile.fit()。
一些背景信息:在抖动中,图像大小不是立即确定的,而是一旦图像实际加载就确定了。这对于少量的图像很好,但是当数量较大(可能无限)时,会引起问题。
这样做的原因是,在第一次构建列表时,它会布局足够的子级以适合屏幕(+ cacheExtent,这可能不适用于StaggeredGridView,但适用于大多数抖动列表)。考虑一下列表中的每个项目将如何布局-GestureDetector,Card,Column和Stack为其子代分配的所有委托(delegate)大小。因此,尺寸取决于图像。占位符并不能真正确定高度,因此您可以想到高度为零或一的图像。
这意味着在您的页面中,随着越来越多的项目添加到屏幕上,它不断尝试加载越来越多的图像-垂直像素数或基本上是无限像素,具体取决于占位符高度的处理方式。
有一个简单的解决方案,但是它可能对您没有吸引力-而不是使用StaggeredTile.fit(),而是使用固定的高度,然后使图像适合该高度。
不幸的是,如果您希望每个图像都具有不同的高度,它将变得更加复杂。解决此问题的一种方法(因为您可以控制数据库)是将纵横比以及每个图像的路径存储在数据库中。这样,您可以使用AspectRatio小部件包装FaceInImage,因此可以立即确定高度。
当然,这仅在您的项目列表不是真正无限的情况下才有效,但是由于它在数据库中,所以我认为假定= D是相当安全的。您可以在PHP中使用the getimagesize function来计算每个图像的长宽比,这样做就可以遍历整个数据库,然后从现在开始,每当插入新图像时,都必须计算长宽比。
另一个解决方案是从您指定自己的固定高度开始,然后在加载图像后更改高度。但是,我不知道StaggeredGridView将如何处理-我见过的大多数列表/网格类都希望他们的 child 保持相同的大小。在这种情况下,您可能必须查看CustomScrollView并编写自己的条,这超出了此问题的范围。
编辑:OP澄清说,显然MySQL部分是他们要问的,而不是为什么它很慢。我仍然认为图像是为什么它慢而不是对URL的请求的原因,但是我可能是错的。尚未指定是要加载10、50、100还是1000张图像。
如果没有更多有关如何设置数据库的知识,就很难给出明确的答案。但是,我将快速概述一下设置服务器的可能方法。
我不会为您的服务器编写实际的代码,因为这超出了关于抖动的SO问题的范围。如果您不知道该如何解决,我建议您先找到一门有关设置服务器的类(class)或教程,然后再问一个问题而不是用flutter标记,而是用PHP / MySQL等标记,因为实际上您对的要求是什么,是关于您遇到的特定问题,而不是一般的“我无法帮助您”的问题,因为这样无法得到解答。
假设以下内容:
{
num: 30,
images: [
{ title: ..., url: ..., .... },
...
],
more: true
}
totalItems
,该返回值作为结果的一部分告诉客户端有多少个图像。您也可以选择接受要退回的商品数量。
num
和
offset
。偏移量应该是描述返回的最后结果的一种方式,以便查询知道从何处开始-如果按ID排序,则可能是那个,或者按日期,可能是日期。
num
将是要返回的最大结果数。
关于android - 用MySQL flutter 无限 ScrollView ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51988852/
我最近在/ drawable中添加了一些.gifs,以便可以将它们与按钮一起使用。这个工作正常(没有错误)。现在,当我重建/运行我的应用程序时,出现以下错误: Error: Gradle: Execu
Android 中有返回内部存储数据路径的方法吗? 我有 2 部 Android 智能手机(Samsung s2 和 s7 edge),我在其中安装了一个应用程序。我想使用位于这条路径中的 sqlit
这个问题在这里已经有了答案: What's the difference between "?android:" and "@android:" in an android layout xml f
我只想知道 android 开发手机、android 普通手机和 android root 手机之间的实际区别。 我们不能从实体店或除 android marketplace 以外的其他地方购买开发手
自Gradle更新以来,我正在努力使这个项目达到标准。这是一个团队项目,它使用的是android-apt插件。我已经进行了必要的语法更改(编译->实现和apt->注释处理器),但是编译器仍在告诉我存在
我是android和kotlin的新手,所以请原谅要解决的一个非常简单的问题! 我已经使用导航体系结构组件创建了一个基本应用程序,使用了底部的导航栏和三个导航选项。每个导航选项都指向一个专用片段,该片
我目前正在使用 Facebook official SDK for Android . 我现在正在使用高级示例应用程序,但我不知道如何让它获取应用程序墙/流/状态而不是登录的用户。 这可能吗?在那种情
我在下载文件时遇到问题, 我可以在模拟器中下载文件,但无法在手机上使用。我已经定义了上网和写入 SD 卡的权限。 我在服务器上有一个 doc 文件,如果用户单击下载。它下载文件。这在模拟器中工作正常但
这个问题在这里已经有了答案: What is the difference between gravity and layout_gravity in Android? (22 个答案) 关闭 9
任何人都可以告诉我什么是 android 缓存和应用程序缓存,因为当我们谈论缓存清理应用程序时,它的作用是,缓存清理概念是清理应用程序缓存还是像内存管理一样主存储、RAM、缓存是不同的并且据我所知,缓
假设应用程序 Foo 和 Eggs 在同一台 Android 设备上。任一应用程序都可以获取设备上所有应用程序的列表。一个应用程序是否有可能知道另一个应用程序是否已经运行以及运行了多长时间? 最佳答案
我有点困惑,我只看到了从 android 到 pc 或者从 android 到 pc 的例子。我需要制作一个从两部手机 (android) 连接的 android 应用程序进行视频聊天。我在想,我知道
用于使用 Android 以编程方式锁定屏幕。我从 Stackoverflow 之前关于此的问题中得到了一些好主意,并且我做得很好,但是当我运行该代码时,没有异常和错误。而且,屏幕没有锁定。请在这段代
文档说: android:layout_alignParentStart If true, makes the start edge of this view match the start edge
我不知道这两个属性和高度之间的区别。 以一个TextView为例,如果我将它的layout_width设置为wrap_content,并将它的width设置为50 dip,会发生什么情况? 最佳答案
这两个属性有什么关系?如果我有 android:noHistory="true",那么有 android:finishOnTaskLaunch="true" 有什么意义吗? 最佳答案 假设您的应用中有
我是新手,正在尝试理解以下 XML 代码: 查看 developer.android.com 上的文档,它说“starStyle”是 R.attr 中的常量, public static final
在下面的代码中,为什么当我设置时单选按钮的外观会发生变化 android:layout_width="fill_parent" 和 android:width="fill_parent" 我说的是
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 9
假设我有一个函数 fun myFunction(name:String, email:String){},当我调用这个函数时 myFunction('Ali', 'ali@test.com ') 如何
我是一名优秀的程序员,十分优秀!