Webview does not scroll smoothly #27180
Scrolling on the webview example is not smooth, also happens with animations. Compare with a native webview embedded on an Android app.
Will it be possible to have smooth scroll using webview or it is a known limitation of platform views?
android studio flutter attach 模式下输出日志
flutter attach does not show logs #70473
flutter logs & flutter attach
动画性能优化
Webview animation is slow on Android #52211
stackoverflow.com/questions/7…
//webview 添加手势
VerticalDragGestureRecognizer
相关代码块
preferredSize: Size(double.infinity, 0),
child: AppBar(
title: Text(""),
backgroundColor: Colors.deepPurple,
),
),
import 'package:webview_flutter/webview_flutter.dart';
import 'package:share/share.dart';
class WebViewPage extends StatefulWidget {
final urllink;
WebViewPage(this.urllink);
@override
_WebViewPageState createState() => _WebViewPageState(this.urllink);
}
class _WebViewPageState extends State<WebViewPage> {
var _url;
final key = UniqueKey();
_WebViewPageState(this._url);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: <Widget>[
IconButton(icon: Icon(Icons.share), onPressed: share)
],
),
body: Column(
children: [
Expanded(
child: WebView(
gestureRecognizers: [Factory<VerticalDragGestureRecognizer>(() => VerticalDragGestureRecognizer())].toSet(),//error line
javascriptMode: JavascriptMode.unrestricted,
key: key,
initialUrl: _url,
),
)
],
),
);
}
void share() {
String shareurl = _url.toString();
Share.share(shareurl);
}
}
最终解决
背景: 混合框架中对flutter webview 做了封装;通过记录用户阅读时长给到响应的奖励; 在webview上会显示一个阅读进度圈圈动画,大概30秒会转一圈;
import 'dart:math';
import 'package:flutter/material.dart';
class GradientCircularProgress extends StatelessWidget {
final double strokeWidth;
final double radius;
final double value;
final bool strokeCapRound;
final Color backgroundColor;
final double totalAngle;
final List<Color> colors;
final List<double> stops;
GradientCircularProgress(
{this.strokeWidth = 2,
@required this.radius,
this.value,
this.strokeCapRound = false,
this.backgroundColor = const Color(0xFFEEEEEE),
this.totalAngle = 2 * pi,
@required this.colors,
this.stops});
@override
Widget build(BuildContext context) {
double _offset = 0;
if (strokeCapRound) {
_offset = asin(strokeWidth / (radius * 2 - strokeWidth));
}
var _colors = colors;
if (_colors == null) {
Color color = Theme.of(context).accentColor;
_colors = [color, color];
}
return Transform.rotate(
angle: -pi / 2 - _offset,
child: CustomPaint(
size: Size.fromRadius(radius),
painter: _GradientCircularProgressPainter(
colors: _colors,
strokeWidth: strokeWidth,
strokeCapRound: strokeCapRound,
backgroundColor: backgroundColor,
value: value,
total: totalAngle,
radius: radius),
),
);
}
}
//画笔
class _GradientCircularProgressPainter extends CustomPainter {
final double strokeWidth;
final bool strokeCapRound;
final double value;
final Color backgroundColor;
final List<Color> colors;
final double total;
final double radius;
final List<double> stops;
_GradientCircularProgressPainter(
{this.strokeWidth: 10.0,
this.strokeCapRound: false,
this.backgroundColor = Colors.white,
this.radius,
this.total = 2 * pi,
@required this.colors,
this.stops,
this.value});
@override
void paint(Canvas canvas, Size size) {
if (radius != null) {
size = Size.fromRadius(radius);
}
double _offset = strokeWidth / 2;
double _value = value ?? 0;
_value = _value.clamp(0, 1) * total;
double _start = 0;
if (strokeCapRound) {
_start = asin(strokeWidth / (size.width - strokeWidth));
}
Rect rect = Offset(_offset, _offset) &
Size(size.width - strokeWidth, size.height - strokeWidth);
var paint = Paint()
..strokeCap = strokeCapRound ? StrokeCap.round : StrokeCap.butt
..style = PaintingStyle.stroke
..isAntiAlias = true
..strokeWidth = strokeWidth;
//backgroundColor
var paint2 = Paint()
..strokeCap = StrokeCap.round
..style = PaintingStyle.stroke
..isAntiAlias = true
..color = Colors.grey[200]
..strokeWidth = strokeWidth;
canvas.drawArc(rect, _start, total, false, paint2);
if (_value > 0) {
paint.shader = SweepGradient(
colors: colors, startAngle: 0, endAngle: _value, stops: stops)
.createShader(rect);
canvas.drawArc(rect, _start, _value, false, paint);
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
```
```
问题
发现部分Android机型滑动不流畅,卡顿感特别明显;
最终定位到是因为这个阅读转圈圈小组件影响;
最后进一步确认只要有webview组件的页面,使用了```AnimationController``` 都会存在卡顿;
AnimationController.value 会不断的进行创建UI;
解决
自己写了一个计时器进行转圈圈动画刷新,300毫秒刷新一次;动画效果也的到保证,webview滑动体验提升300%