英文:
Disabling scroll of first item in ListWheelScrollView in flutter
问题
以下是您提供的内容的翻译:
如何停止ListWheelScrollView
在第一个索引处滚动。
期望输出: -
当ListWheelScrollView
遇到禁用项或ListView的第一个索引时,应停止滚动。滚动索引不应计算第一个索引,也就是说它不应继续向前移动或到达禁用的索引。
期望输出GIF: -
代码: -
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'List',
theme: ThemeData(
primarySwatch: Colors.blue,
),
debugShowCheckedModeBanner: false,
home: const List(),
);
}
}
class List extends StatefulWidget {
const List({Key? key}) : super(key: key);
@override
_ListState createState() => _ListState();
}
class _ListState extends State<List> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("List"),
backgroundColor: Colors.green,
),
body: Center(
child: Stack(
alignment: AlignmentDirectional.center,
children: [
RotatedBox(
quarterTurns: 1,
child: SizedBox(
height: 600,
width: 800,
child: ListWheelScrollView(
itemExtent: 100,
physics: const FixedExtentScrollPhysics(),
onSelectedItemChanged: (value) {},
children: [
for (int i = 0; i < 4; i++) ...[
Container(
color: i != 3 ? Colors.green[200] : Colors.red[200],
height: 70,
width: 70,
alignment: Alignment.center,
child: RotatedBox(
quarterTurns: -1,
child: Text(i != 3 ? "Enabled" : "Disabled")),
)
]
]),
),
),
const Positioned(top: 440, child: Icon(Icons.arrow_circle_up))
],
),
));
}
}
提供的一个解决方案: -
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'List',
theme: ThemeData(
primarySwatch: Colors.blue,
),
debugShowCheckedModeBanner: false,
home: const ScrollingList(),
);
}
}
class ScrollingList extends StatefulWidget {
const ScrollingList({Key? key}) : super(key: key);
@override
_ScrollingListState createState() => _ScrollingListState();
}
class _ScrollingListState extends State<ScrollingList> {
final controller = FixedExtentScrollController();
final children = [
for (int i = 0; i < 6; i++) ScrollingListItem(enabled: i != 0)
];
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("List"),
backgroundColor: Colors.green,
),
body: Center(
child: Stack(
alignment: AlignmentDirectional.center,
children: [
RotatedBox(
quarterTurns: 1,
child: SizedBox(
height: 600,
width: 800,
child: ListWheelScrollView(
controller: controller,
itemExtent: 100,
physics: const FixedExtentScrollPhysics(),
onSelectedItemChanged: (idx) {
if (!children[idx].enabled) {
controller.animateToItem(
idx + 1,
duration: const Duration(milliseconds: 500),
curve: Curves.linear,
);
}
},
children: children,
),
),
),
const Positioned(top: 440, child: Icon(Icons.arrow_circle_up))
],
),
));
}
}
class ScrollingListItem extends StatelessWidget {
final bool enabled;
const ScrollingListItem({Key? key, required this.enabled});
@override
Widget build(BuildContext context) {
return Container(
color: enabled ? Colors.green[200] : Colors.red[200],
height: 70,
width: 70,
alignment: Alignment.center,
child: RotatedBox(
quarterTurns: -1,
child: Text(
enabled ? "Enabled" : "Disabled",
),
),
);
}
}
其中有一个bug,当List Wheel滚动到禁用元素时,最后一个元素(极左侧容器)会闪烁: -
英文:
How to stop scrolling of ListWheelScrollView
for the first index.
Expected Output : -
ListWheelScrollView
should stop scrolling when it encounters a disabled item or the first index of ListView. Scroll index should not count the first index, that is it should not move further or to the disabled index.
Expected Output GIF : -
<img src="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExMGZmNGU1ODMzMTUzMWFjYTY5ZDA4ZTkzZDkzOWMzYmU3ODY0MDE0MCZlcD12MV9pbnRlcm5hbF9naWZzX2dpZklkJmN0PWc/r6Tj1PNNYuGkm5ZnEy/giphy.gif">
Code : -
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'List',
theme: ThemeData(
primarySwatch: Colors.blue,
),
debugShowCheckedModeBanner: false,
home: const List(),
);
}
}
class List extends StatefulWidget {
const List({Key? key}) : super(key: key);
@override
_ListState createState() => _ListState();
}
class _ListState extends State<List> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("List"),
backgroundColor: Colors.green,
),
body: Center(
child: Stack(
alignment: AlignmentDirectional.center,
children: [
RotatedBox(
quarterTurns: 1,
child: SizedBox(
height: 600,
width: 800,
child: ListWheelScrollView(
itemExtent: 100,
physics: const FixedExtentScrollPhysics(),
onSelectedItemChanged: (value) {},
children: [
for (int i = 0; i < 4; i++) ...[
Container(
color: i != 3 ? Colors.green[200] : Colors.red[200],
height: 70,
width: 70,
alignment: Alignment.center,
child: RotatedBox(
quarterTurns: -1,
child: Text(i != 3 ? "Enabled" : "Disabled")),
)
]
]),
),
),
const Positioned(top: 440, child: Icon(Icons.arrow_circle_up))
],
),
));
}
}
One solution provided : -
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'List',
theme: ThemeData(
primarySwatch: Colors.blue,
),
debugShowCheckedModeBanner: false,
home: const ScrollingList(),
);
}
}
class ScrollingList extends StatefulWidget {
const ScrollingList({Key? key}) : super(key: key);
@override
_ScrollingListState createState() => _ScrollingListState();
}
class _ScrollingListState extends State<ScrollingList> {
final controller = FixedExtentScrollController();
final children = [
for (int i = 0; i < 6; i++) ScrollingListItem(enabled: i != 0)
];
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("List"),
backgroundColor: Colors.green,
),
body: Center(
child: Stack(
alignment: AlignmentDirectional.center,
children: [
RotatedBox(
quarterTurns: 1,
child: SizedBox(
height: 600,
width: 800,
child: ListWheelScrollView(
controller: controller,
itemExtent: 100,
physics: const FixedExtentScrollPhysics(),
onSelectedItemChanged: (idx) {
if (!children[idx].enabled) {
controller.animateToItem(
idx + 1,
duration: const Duration(milliseconds: 500),
curve: Curves.linear,
);
}
},
children: children,
),
),
),
const Positioned(top: 440, child: Icon(Icons.arrow_circle_up))
],
),
));
}
}
class ScrollingListItem extends StatelessWidget {
final bool enabled;
const ScrollingListItem({super.key, required this.enabled});
@override
Widget build(BuildContext context) {
return Container(
color: enabled ? Colors.green[200] : Colors.red[200],
height: 70,
width: 70,
alignment: Alignment.center,
child: RotatedBox(
quarterTurns: -1,
child: Text(
enabled ? "Enabled" : "Disabled",
),
),
);
}
}
It has a bug , the last element(extreme left container) will flash when List Wheel is moved to the disable element : -
<img src="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExYWJkMzVkMWI5M2JjNDRkYThiOTM2MTA4MWJhYmYzMWU3ODQwN2U0ZiZlcD12MV9pbnRlcm5hbF9naWZzX2dpZklkJmN0PWc/mj2sQyJVRabf6xjTEa/giphy.gif">
答案1
得分: 1
以下是您提供的代码的中文翻译:
以下代码与您提供的解决方案类似,但有一些小改动。
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'List',
theme: ThemeData(
primarySwatch: Colors.blue,
),
debugShowCheckedModeBanner: false,
home: const ScrollingList(),
);
}
}
class ScrollingList extends StatefulWidget {
const ScrollingList({Key? key}) : super(key: key);
@override
_ScrollingListState createState() => _ScrollingListState();
}
class _ScrollingListState extends State<ScrollingList> {
final controller = FixedExtentScrollController(initialItem: 1);
final children = [
for (int i = 0; i < 6; i++) ScrollingListItem(enabled: i != 0)
];
void scrollListener() {
if (controller.selectedItem == 1) {
if (controller.position.userScrollDirection == ScrollDirection.forward) {
controller.jumpToItem(1);
}
}
}
@override
void initState() {
super.initState();
controller.addListener(scrollListener);
}
@override
void dispose() {
controller.removeListener(scrollListener);
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("List"),
backgroundColor: Colors.green,
),
body: Center(
child: Stack(
alignment: AlignmentDirectional.center,
children: [
RotatedBox(
quarterTurns: 1,
child: SizedBox(
height: 600,
width: 800,
child: ListWheelScrollView(
controller: controller,
itemExtent: 100,
physics: const FixedExtentScrollPhysics(),
// onSelectedItemChanged: (idx) {
// if (!children[idx].enabled) {
// controller.animateToItem(
// idx + 1,
// duration: const Duration(milliseconds: 500),
// curve: Curves.linear,
// );
// }
// },
children: children,
),
),
),
const Positioned(top: 440, child: Icon(Icons.arrow_circle_up))
],
),
));
}
}
class ScrollingListItem extends StatelessWidget {
final bool enabled;
const ScrollingListItem({super.key, required this.enabled});
@override
Widget build(BuildContext context) {
return Container(
color: enabled ? Colors.green[200] : Colors.red[200],
height: 70,
width: 70,
alignment: Alignment.center,
child: RotatedBox(
quarterTurns: -1,
child: Text(
enabled ? "Enabled" : "Disabled",
),
),
);
}
}
希望对您有所帮助。谢谢 :)
英文:
The following code is similar to your provided solution but with little changes.
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'List',
theme: ThemeData(
primarySwatch: Colors.blue,
),
debugShowCheckedModeBanner: false,
home: const ScrollingList(),
);
}
}
class ScrollingList extends StatefulWidget {
const ScrollingList({Key? key}) : super(key: key);
@override
_ScrollingListState createState() => _ScrollingListState();
}
class _ScrollingListState extends State<ScrollingList> {
final controller = FixedExtentScrollController(initialItem: 1);
final children = [
for (int i = 0; i < 6; i++) ScrollingListItem(enabled: i != 0)
];
void scrollListener() {
if (controller.selectedItem == 1) {
if (controller.position.userScrollDirection == ScrollDirection.forward) {
controller.jumpToItem(1);
}
}
}
@override
void initState() {
super.initState();
controller.addListener(scrollListener);
}
@override
void dispose() {
controller.removeListener(scrollListener);
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("List"),
backgroundColor: Colors.green,
),
body: Center(
child: Stack(
alignment: AlignmentDirectional.center,
children: [
RotatedBox(
quarterTurns: 1,
child: SizedBox(
height: 600,
width: 800,
child: ListWheelScrollView(
controller: controller,
itemExtent: 100,
physics: const FixedExtentScrollPhysics(),
// onSelectedItemChanged: (idx) {
// if (!children[idx].enabled) {
// controller.animateToItem(
// idx + 1,
// duration: const Duration(milliseconds: 500),
// curve: Curves.linear,
// );
// }
// },
children: children,
),
),
),
const Positioned(top: 440, child: Icon(Icons.arrow_circle_up))
],
),
));
}
}
class ScrollingListItem extends StatelessWidget {
final bool enabled;
const ScrollingListItem({super.key, required this.enabled});
@override
Widget build(BuildContext context) {
return Container(
color: enabled ? Colors.green[200] : Colors.red[200],
height: 70,
width: 70,
alignment: Alignment.center,
child: RotatedBox(
quarterTurns: -1,
child: Text(
enabled ? "Enabled" : "Disabled",
),
),
);
}
}
Hope it helps.
Thanks
答案2
得分: -1
以下是翻译好的部分:
你需要一种方法来检测当前的 index
是否被禁用,以充分利用与 FixedExtentScrollController
配对的 onSelectedItemChanged
(不要忘记释放资源!),以平滑地滚动到你正在滚动到的项目的中心,使用 animateToItem()
。你可以通过一个具有启用/禁用 bool
的类来实现这一点。
(还请不要将类命名为Dart关键字)
这是一个简单的工作示例。
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'List',
theme: ThemeData(
primarySwatch: Colors.blue,
),
debugShowCheckedModeBanner: false,
home: const ScrollingList(),
);
}
}
class ScrollingList extends StatefulWidget {
const ScrollingList({Key? key}) : super(key: key);
@override
_ScrollingListState createState() => _ScrollingListState();
}
class _ScrollingListState extends State<ScrollingList> {
final controller = FixedExtentScrollController();
final children = [
for (int i = 0; i < 6; i++) ScrollingListItem(enabled: i != 3)
];
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("List"),
backgroundColor: Colors.green,
),
body: Center(
child: Stack(
alignment: AlignmentDirectional.center,
children: [
RotatedBox(
quarterTurns: 1,
child: SizedBox(
height: 600,
width: 800,
child: ListWheelScrollView(
controller: controller,
itemExtent: 100,
physics: const FixedExtentScrollPhysics(),
onSelectedItemChanged: (idx) {
if (!children[idx].enabled) {
controller.animateToItem(
idx,
duration: const Duration(milliseconds: 500),
curve: Curves.linear,
);
}
},
children: children,
),
),
),
const Positioned(top: 440, child: Icon(Icons.arrow_circle_up))
],
),
));
}
}
class ScrollingListItem extends StatelessWidget {
final bool enabled;
const ScrollingListItem({Key? key, required this.enabled});
@override
Widget build(BuildContext context) {
return Container(
color: enabled ? Colors.green[200] : Colors.red[200],
height: 70,
width: 70,
alignment: Alignment.center,
child: RotatedBox(
quarterTurns: -1,
child: Text(
enabled ? "Enabled" : "Disabled",
),
),
);
}
}
英文:
You would need a way to detect that the current index
is disabled to take advantage of the onSelectedItemChanged
paired with a FixedExtentScrollController
(don't forget to dispose!) to smoothly go to the center of the item you're scrolling into using animateToItem()
. You can do this with a class having a enabled/disabled bool
.
(Also don't name classes the same as dart keywords)
Here's a simple working example.
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'List',
theme: ThemeData(
primarySwatch: Colors.blue,
),
debugShowCheckedModeBanner: false,
home: const ScrollingList(),
);
}
}
class ScrollingList extends StatefulWidget {
const ScrollingList({Key? key}) : super(key: key);
@override
_ScrollingListState createState() => _ScrollingListState();
}
class _ScrollingListState extends State<ScrollingList> {
final controller = FixedExtentScrollController();
final children = [
for (int i = 0; i < 6; i++) ScrollingListItem(enabled: i != 3)
];
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("List"),
backgroundColor: Colors.green,
),
body: Center(
child: Stack(
alignment: AlignmentDirectional.center,
children: [
RotatedBox(
quarterTurns: 1,
child: SizedBox(
height: 600,
width: 800,
child: ListWheelScrollView(
controller: controller,
itemExtent: 100,
physics: const FixedExtentScrollPhysics(),
onSelectedItemChanged: (idx) {
if (!children[idx].enabled) {
controller.animateToItem(
idx,
duration: const Duration(milliseconds: 500),
curve: Curves.linear,
);
}
},
children: children,
),
),
),
const Positioned(top: 440, child: Icon(Icons.arrow_circle_up))
],
),
));
}
}
class ScrollingListItem extends StatelessWidget {
final bool enabled;
const ScrollingListItem({super.key, required this.enabled});
@override
Widget build(BuildContext context) {
return Container(
color: enabled ? Colors.green[200] : Colors.red[200],
height: 70,
width: 70,
alignment: Alignment.center,
child: RotatedBox(
quarterTurns: -1,
child: Text(
enabled ? "Enabled" : "Disabled",
),
),
);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论