你好,我是一名移动应用开发者,对于Web开发不太熟悉。我正在寻找一种方法,在加载Flutter web应用程序之前实现进度指示器,就像Gmail加载屏幕一样。Flutter web很酷,但在加载应用程序之前需要等待几秒钟。我们能否添加任何指示器来表示此加载时间?在Flutter中实现的任何代码都将成为Flutter应用程序的一部分,并且它不起作用,因此必须采取另一种方法来实现此目标。
你好,我是一名移动应用开发者,对于Web开发不太熟悉。我正在寻找一种方法,在加载Flutter web应用程序之前实现进度指示器,就像Gmail加载屏幕一样。Flutter web很酷,但在加载应用程序之前需要等待几秒钟。我们能否添加任何指示器来表示此加载时间?在Flutter中实现的任何代码都将成为Flutter应用程序的一部分,并且它不起作用,因此必须采取另一种方法来实现此目标。
在 @Abhilash 的帮助下,我成功完成了这个任务。我从 w3schools 获取了加载器代码。
我的 project/web/index.html
文件如下。
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
<script defer src="index.dart.js" type="application/javascript"></script>
<style>
.loading {
display: flex;
justify-content: center;
align-items: center;
margin: 0;
position: absolute;
top: 50%;
left: 50%;
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
.loader {
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid blue;
border-right: 16px solid green;
border-bottom: 16px solid red;
border-left: 16px solid pink;
width: 120px;
height: 120px;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
}
@-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
</head>
<body>
<div class="loading">
<div class="loader"></div>
</div>
<script src="main.dart.js" type="application/javascript"></script>
</body>
</html>
在你的问题中,你提到:
任何在Flutter中实现的代码都是Flutter应用程序的一部分,它将无法运行...
我猜你试着为Android或iOS添加启动画面。因为Flutter Web只是一个index.html
和几个js文件(例如main.dart.js
),你可以尝试使用CSS
加载动画技巧。由于你没有分享任何代码,所以我不会写任何代码,但以下是我的方法,如这个red stapler视频中解释的那样。他/她在这里提供了许多基于CSS
的动画,包括其codepen实现。
因此,以下是我在flutter_web_project\web\index.html
文件中的步骤:
index.html
的body中添加一个元素来显示css
动画本身。index.html
中的位置。onLoad
事件,并从你的页面中删除loading
div
,因为在Safari浏览器中可能会导致闪烁。 因此,您需要在第一个屏幕上实现以下代码(例如,在initState
方法中):import 'package:universal_html/html.dart'
...
@override
void initState() {
super.initState()
// Remove `loading` div
final loader = document.getElementsByClassName('loading');
if(loader.isNotEmpty) {
loader.first.remove();
}
}
P.S. 如果你需要漂亮的加载动画,可以访问 loading.io。
Adam的回答会在Flutter实际加载之前移除加载器。
我认为这个脚本是最完整的答案:
<html>
<head>
<style>
.loading {
display: flex;
flex-flow: column;
justify-content: center;
align-items: center;
margin: 0;
position: absolute;
top: 50%;
left: 50%;
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
.loader {
border: 8px solid #f3f3f3;
border-radius: 50%;
border-top: 8px solid #00AD87;
border-right: 8px solid #C30E48;
border-bottom: 8px solid #00AD87;
border-left: 8px solid #C30E48;
width: 60px !important;
height: 60px !important;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
}
@-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
</head>
<body>
<!-- First time loading -->
<div class="loading">
<div class="loader"></div>
</div>
<!-- Ensure first time loading progress is gone after app loads -->
<script>
window.addEventListener("flutter-first-frame", function() {
var element = document.getElementsByClassName("loading");
element[0].parentNode.removeChild(element[0]);
});
</script>
<script defer src="main.dart.js" type="application/javascript"</script>
<script>
window.onload = (event) => {
console.log('page is fully loaded');
var element = document.getElementById("loader");
element.parentNode.removeChild(element);
};
</script>
<div id="loader"></div>
标签。<script defer src="main.dart.js" type="application/javascript"></script>
以下是我需要这样做的情况:
在这种情况下,只有空白屏幕可见,直到整个脚本下载完成。然后动画仅可见0.5秒,Flutter小部件立即加载。因此无法实现加载动画的目的。在本地测试中不会发生这种情况。
我还尝试将动画div放在所有脚本之前,但没有帮助。
我认为被接受的答案部分正确,因为它呈现了一个加载指示器而不是进度指示器。从flutter doc中,您可以大致估计Flutter的实际加载进度。我使用this indicator编译了一个示例,并在此处展示。
添加这个样式
.container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
width: 100%;
}
.progress-bar__container {
width: 80%;
height: 2rem;
border-radius: 2rem;
position: relative;
overflow: hidden;
transition: all 0.5s;
will-change: transform;
box-shadow: 0 0 5px #e76f51;
}
.progress-bar {
position: absolute;
height: 100%;
width: 100%;
content: "";
background-color: #e76f51;
top:0;
bottom: 0;
left: -100%;
border-radius: inherit;
display: flex;
justify-content: center;
align-items:center;
color: white;
font-family: sans-serif;
}
.progress-bar__text {
display: none;
}
并将此代码附加到您的Flutter应用程序的index.html
中。
function updateProgress(num) {
const progressBarContainer = document.querySelector('.progress-bar__container');
const progressBar = document.querySelector('.progress-bar');
const progressBarText = document.querySelector('.progress-bar__text');
let time = 0;
let endState = 100;
gsap.to(progressBar, {
x: num + "%",
duration: 2,
});
}
window.addEventListener('load', function(ev) {
var loading = document.querySelector('#loading');
loading.textContent = "Loading entrypoint...";
updateProgress(15);
_flutter.loader.loadEntrypoint({
serviceWorker: {
serviceWorkerVersion: serviceWorkerVersion,
},
onEntrypointLoaded: async function(engineInitializer) {
loading.textContent = "Initializing engine...";
updateProgress(50);
let appRunner = await engineInitializer.initializeEngine();
updateProgress(80);
loading.textContent = "Running app...";
await appRunner.runApp();
updateProgress(100);
}
});
});
我按照此人描述的方式进行操作:https://retroportalstudio.medium.com/indicate-website-loading-for-flutter-web-apps-7dc5e2c59e24
然后,在我的Flutter应用程序中,我显示了这个指示器:
return Container( decoration: BoxDecoration(color: Colors.white), child: Center(child: CircularProgressIndicator()) );
这个指示器与 gif 差不多。我使用 https://gifcap.dev/ 和 gimp 的组合来裁剪它,制作了这个 gif。
结果是一个相当平滑的加载圆形进度指示器,几乎在打开我的网站时立即出现,一直到我的 flutterweb 应用程序打开。