I have 2 button, to control a scrolling of InteractiveViewer widget, left and right, hopefully I can add up and down later own my own after i have better understanding of matrix4Tween
right now the button is as such
Row(
children: [
ElevatedButton(
onPressed: () {
controller.value = Matrix4.identity()..translate(0.0, 0.0);
},
child: Text('<'),
),
ElevatedButton(
onPressed: () {
controller.value = Matrix4.identity()..translate(-(width), 0.0);
},
child: Text('>'),
),
],
),
and below it is a interactiveViewer widget that contains 4 gridview
Container(
color: Colors.grey,
width: gridboxwidth,
height: gridboxheight,
child: InteractiveViewer(
alignPanAxis: true,
constrained: false,
transformationController: controller,
scaleEnabled: true,
minScale: 0.1,
maxScale: 1,
child: Column(
children: [
Row(
children: [
grid1(size),
grid3(size),
],
),
Row(
children: [
grid2(size),
grid4(size),
],
),
],
),
),
),
and it works just fine, on tap of the button, the grid moves into view, but I don't think it is intuitive enough and some animation might need to be added to show that the grid has changed.
Any help and guidance is greatly appreciated.
CodePudding user response:
this is a sample widget that uses Matrix4Tween
, the important lines of code are marked with // NOTE:
comments:
class FooInteractiveViewer extends StatefulWidget {
@override
_FooInteractiveViewerState createState() => _FooInteractiveViewerState();
}
class _FooInteractiveViewerState extends State<FooInteractiveViewer> with TickerProviderStateMixin {
AnimationController _ctrl;
Animation<Matrix4> _matrixAnimation = AlwaysStoppedAnimation(Matrix4.identity());
final _transformationController = TransformationController();
@override
void initState() {
super.initState();
_ctrl = AnimationController(
vsync: this,
duration: Duration(milliseconds: 500),
)
// NOTE: add listener to be called each time _ctrl changes
..addListener(_listener);
}
void _listener() {
print(MatrixUtils.transformPoint(_matrixAnimation.value, Offset.zero));
// NOTE: this is the most important part of this code:
_transformationController.value = _matrixAnimation.value;
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
return InteractiveViewer(
// panEnabled: false,
alignPanAxis: true,
constrained: false,
transformationController: _transformationController,
child: SizedBox(
width: constraints.maxWidth * 2,
height: constraints.maxHeight * 2,
child: Column(
children: [
Expanded(
child: Row(
children: [
button(Colors.red, constraints.biggest, 1, 0, 'green'),
button(Colors.green, constraints.biggest, 0, 1, 'blue'),
],
),
),
Expanded(
child: Row(
children: [
button(Colors.blue, constraints.biggest, 1, 1, 'orange'),
button(Colors.orange, constraints.biggest, 0, 0, 'red'),
],
),
),
],
),
)
);
},
);
}
Widget button(Color color, Size size, int x, int y, String name) {
return Expanded(
child: Material(
color: color,
child: InkWell(
onTap: () async {
// timeDilation = 10;
// NOTE: create new Animation<Matrix4> that will be used inside _listener
_matrixAnimation = Matrix4Tween(
begin: _transformationController.value,
end: Matrix4.translationValues(-size.width * x, -size.height * y, 0)
).chain(CurveTween(curve: Curves.decelerate)).animate(_ctrl);
// NOTE: lets start the show
await _ctrl.forward(from: 0);
print('### animation finished ###');
},
child: Center(child: Text('go to $name', textScaleFactor: 2)),
),
),
);
}
@override
void dispose() {
super.dispose();
_ctrl.dispose();
}
}