#recursion #dart #flutter
#рекурсия #dart #флаттер
Вопрос:
Синхронизация прокрутки для нескольких прокручиваемых виджетов:
Я хочу прокрутить второй список, если прокрутить первый список, и прокрутить первый список, если прокрутить второй список.Это будет рекурсивно, кто-нибудь может помочь в этом, заранее спасибо.
import 'package:flutter/cupertino.dart';
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
ScrollController firstScroll = ScrollController();
ScrollController secondScrollController = ScrollController();
@override
void initState() {
super.initState();
firstScroll.addListener(() {
//THIS IS called when scroll is triggered,
secondScrollController
.jumpTo(firstScroll.offset); // THIS will sync the scroll;
});
secondScrollController.addListener(() {
//THIS IS called when scroll is triggered,
firstScroll
.jumpTo(secondScrollController.offset); // THIS will sync the scroll;
});
}
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: <Widget>[
SingleChildScrollView(
// this is the first scroll
scrollDirection: Axis.horizontal,
controller: firstScroll, // THIS IS THE FIRST SCROLL CONTROLLER
child: Container(
//TODO: add your content here here
),
),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
controller: secondScrollController,
// HERE YOU SET THE SECOND CONTROLLER
child: Container(
//TODO: add your content here
),
)
],
),
);
}
}
Ответ №1:
Это потому, что каждый раз, когда вы вызываете jumpTo
метод, он вызывает первый, а первый вызывает второй, и у вас будет бесконечный цикл.
Решение заключается в том, что вы создаете свой собственный ScrollController, которому принадлежит метод перехода на другую позицию без уведомления.
Это пользовательский контроллер прокрутки, который вы можете создать:
class CustomScrollController extends ScrollController {
CustomScrollController({
double initialScrollOffset = 0.0,
keepScrollOffset = true,
debugLabel,
}) : super(
initialScrollOffset: initialScrollOffset,
keepScrollOffset: keepScrollOffset,
debugLabel: debugLabel);
@override
_UnboundedScrollPosition createScrollPosition(
ScrollPhysics physics,
ScrollContext context,
ScrollPosition oldPosition,
) {
return _UnboundedScrollPosition(
physics: physics,
context: context,
oldPosition: oldPosition,
initialPixels: initialScrollOffset,
);
}
void jumpToWithoutGoingIdleAndKeepingBallistic(double value) {
assert(positions.isNotEmpty, 'ScrollController not attached.');
for (_UnboundedScrollPosition position
in new List<ScrollPosition>.from(positions))
position.jumpToWithoutGoingIdleAndKeepingBallistic(value);
}
}
class _UnboundedScrollPosition extends ScrollPositionWithSingleContext {
_UnboundedScrollPosition({
ScrollPhysics physics,
ScrollContext context,
ScrollPosition oldPosition,
double initialPixels,
}) : super(
physics: physics,
context: context,
oldPosition: oldPosition,
initialPixels: initialPixels,
);
/// There is a feedback-loop between aboveController and belowController. When one of them is
/// being used, it controls the other. However if they get out of sync, for timing reasons,
/// the controlled one with try to control the other, and the jump will stop the real controller.
/// For this reason, we can't let one stop the other (idle and ballistics) in this situation.
void jumpToWithoutGoingIdleAndKeepingBallistic(double value) {
if (pixels != value) {
forcePixels(value);
}
}
}
И просто позвоните , чтобы jumpToWithoutGoingIdleAndKeepingBallistic
вместо jumpTo
.
Рабочий образец здесь:
https://gist.github.com/diegoveloper/75e55ca2e4cee03bff41a26254d6fcf6
Результат
Комментарии:
1. Спасибо за решение, но если я попробую так, эффект отскока отсутствует, и список отображается даже для пустого пространства. (т.е. Больше, чем размер) добавлено изображение, о котором идет речь.
2. shrinkWrap: верно, удалите эффект подпрыгивания вашего списка, если вы удалите это значение, у вас могут возникнуть некоторые проблемы в вашем макете, попробуйте использовать Slivers
3. Это единственный дочерний контроллер прокрутки, и мы хотим, чтобы эффект подпрыгивания соответствовал требованиям
4. извините, я обновил свой код: проверьте еще раз -> gist.github.com/diegoveloper/75e55ca2e4cee03bff41a26254d6fcf6
5. Не работает чувак. эффект отскока не появляется, и прокрутка не бесплатна. это рывок.