我想實現一個水平滾動的價值選擇,與此類似: 撲:如何創建一個自定義滾動部件
用戶滾動「磁帶」向左或向右,選擇價值(顯示在中間的框中)。該磁帶具有最大值和最小值,當達到該值時將顯示典型的過捲動畫(Android上發光; iOS上反彈)。
Hixie在Gitter上建議我可以使用GestureDetector
+ CustomPaint
,但我有一種感覺,我必須自己實現滾動邏輯,並且不會利用Flutter的fling和overscroll實現。
編輯:在進一步調查之後,我改變了原來的做法使用低級別的小部件,如Scrollable
和Viewport
即得。
我已經能夠創建磁帶通過擴展CustomPaint
,其寬度設置爲帶全長: _width = (_maxValue - _minValue) * _spacing;
然後,我把我的自定義窗口小部件CustomScrollView內:
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
runApp(new MaterialApp(home: new Scaffold(
appBar: new AppBar(title: new Text("Test"),),
body: new CustomScrollView(
scrollDirection: Axis.horizontal,
slivers: <Widget>[
new SliverToBoxAdapter(
child: new Tape(),
)
],
)
)));
}
const _width = (_maxValue - _minValue) * spacing;
const spacing = 20.0;
const _minValue = 0;
const _maxValue = 100;
class Tape extends CustomPaint {
Tape() : super(
size: new Size(_width, 60.0),
painter: new _TapePainter(),
);
}
class _TapePainter extends CustomPainter {
Paint _tickPaint;
_TapePainter() {
_tickPaint = new Paint();
_tickPaint.color = Colors.black;
_tickPaint.strokeWidth = 1.0;
}
@override
void paint(Canvas canvas, Size size) {
var rect = Offset.zero & size;
var o1 = new Offset(0.0, 0.0);
var o2 = new Offset(0.0, rect.height);
while (o1.dx < size.width) {
canvas.drawLine(o1, o2, _tickPaint);
o1 = o1.translate(spacing, 0.0);
o2 = o2.translate(spacing, 0.0);
}
}
@override
bool shouldRepaint(_TapePainter oldDelegate) {
return true;
}
}
這實現了我想要的效果:我現在可以左右滾動錄像帶,並免費獲得超滾動效果。
問題是,當前的代碼效率低下:整個磁帶被繪製一次,滾動只是簡單地移動緩衝的位圖。這對非常大的「磁帶」造成問題。
相反,我正在尋找的是在每個框架上重新繪製小部件,以便只需要計算和繪製可見部分。這也將允許我實現其他滾動相關效果,例如,在接近中心時動態地衰減數字。
這是一個類似的目標,但你的實現是基於管理所有的圖紙給你一個ListView。 我更願意自己做繪畫,同時利用現有的Flutter滾動實現。 – Cachapa
這就是我想的:(嗯,請分享代碼或github鏈接,當你將處理這個。我很樂意看到它在你的方式工作:) –
會做。該計劃是將其作爲通用小部件發佈。 – Cachapa