When I scale a horizontal ListView
widget, I observe that only a portion of the list items are visible when the widget is scrolled all the way to the right:
import 'dart:ui';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final sideLength = 50.0;
final scale = 2.0;
return MaterialApp(
scrollBehavior: MyCustomScrollBehavior(),
home: Scaffold(
body: Transform.scale(
scale: scale,
alignment: Alignment(-1, -1),
child: Container(
height: sideLength * scale,
child: ListView.builder(
itemCount: 20,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) => Container(
width: sideLength,
height: sideLength,
child: Text(index.toString()),
decoration: BoxDecoration(
border: Border.all(width: 3, color: Colors.red))),
)),
)));
}
}
class MyCustomScrollBehavior extends MaterialScrollBehavior {
// Override behavior methods and getters like dragDevices
@override
Set<PointerDeviceKind> get dragDevices => {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
};
}
On the Pixel 2 emulator, only the first 16 items are visible when I scroll to extreme right. For example:
When the scale is 1 or if the Transform.scale
widget is not there, all 20 items are visible.
I observe the following behavior:
Total item count | Last item scrollable to |
---|---|
8 | 4 |
10 | 6 |
20 | 16 |
30 | 26 |
50 | 46 |
So it seems like the last 4 items are always left out.
Ultimately my goal is to create a responsive widget that scales according to the dimensions of screen, so I'm looking for a generic solution.
The custom scroll behavior is only there so that horizontal scrolling works on dartpad.dev, as per this answer.
CodePudding user response:
Transform only affects how the child should be painted.
On the other hand, The scale argument multiplies the x and y axes.
For example: Imagine a photographer who is taking a landscape photo that contains a tree, now if the photographer gets closer to the tree, the upper part of the tree will slightly be out of the photo.
Try adding padding or margin to the Container and observe how the widget is affected by the scale. Then you will know how to manipulate it.
body: Transform.scale(
scale: scale,
alignment: Alignment(0, -5),
child: Container(
height: sideLength * scale,
margin: EdgeInsets.only(left: 100, right: 100),
child: ListView.builder(
CodePudding user response:
Give here width and height by MediaQuery
Widget build(BuildContext context) {
return MaterialApp(
scrollBehavior: MyCustomScrollBehavior(),
home: Scaffold(
body: Transform.scale(
scale: scale,
alignment: Alignment(-1, -1),
child: Container(
height: sideLength * scale,
child: ListView.builder(
itemCount: 20,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) => Container(
width: MediaQuery.of(context).size.width*0.90 ,
height: MediaQuery.of(context).size.height*0.80 ,
child: Text(index.toString()),
decoration: BoxDecoration(
border: Border.all(width: 3, color: Colors.red))),
)),
)));
}