#dart #flutter
#dart #флаттер
Вопрос:
В настоящее время я использую библиотеку carousel-slider, чтобы получить карусель в Flutter.
Эта библиотека основана на просмотре страницы, а в просмотре страницы элементы центрируются.
Это карусель, которую я получаю:
И это то, что я хотел бы иметь:
Вот код, в котором используется карусель Slider:
CarouselSlider(
height: 150,
viewportFraction: 0.5,
initialPage: 0,
enableInfiniteScroll: false,
items: widget.user.lastGamesPlayed.map((game) {
return Builder(
builder: (BuildContext context) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: GestureDetector(
onTap: () {
game.presentGame(context, widget.user);
},
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(25)),
child: Container(
color: Theme.MyColors.lightBlue,
child: Center(
child: Padding(
padding: EdgeInsets.all(20),
child: AutoSizeText(game.name,
style: TextStyle(fontSize: 70),
maxLines: 1)),
),
))));
},
);
}).toList(),
)
И вот код внутри библиотеки CarouselSlider:
@override
Widget build(BuildContext context) {
return getWrapper(PageView.builder(
physics: widget.isScrollEnabled
? AlwaysScrollableScrollPhysics()
: NeverScrollableScrollPhysics(),
scrollDirection: widget.scrollDirection,
controller: widget.pageController,
reverse: widget.reverse,
itemCount: widget.enableInfiniteScroll ? null : widget.items.length,
onPageChanged: (int index) {
int currentPage =
_getRealIndex(index, widget.realPage, widget.items.length);
if (widget.onPageChanged != null) {
widget.onPageChanged(currentPage);
}
},
itemBuilder: (BuildContext context, int i) {
final int index = _getRealIndex(
i widget.initialPage, widget.realPage, widget.items.length);
return AnimatedBuilder(
animation: widget.pageController,
child: widget.items[index],
builder: (BuildContext context, child) {
// on the first render, the pageController.page is null,
// this is a dirty hack
if (widget.pageController.position.minScrollExtent == null ||
widget.pageController.position.maxScrollExtent == null) {
Future.delayed(Duration(microseconds: 1), () {
setState(() {});
});
return Container();
}
double value = widget.pageController.page - i;
value = (1 - (value.abs() * 0.3)).clamp(0.0, 1.0);
final double height = widget.height ??
MediaQuery.of(context).size.width * (1 / widget.aspectRatio);
final double distortionValue = widget.enlargeCenterPage
? Curves.easeOut.transform(value)
: 1.0;
if (widget.scrollDirection == Axis.horizontal) {
return Center(
child:
SizedBox(height: distortionValue * height, child: child));
} else {
return Center(
child: SizedBox(
width:
distortionValue * MediaQuery.of(context).size.width,
child: child));
}
},
);
},
));
}
Как я могу предотвратить центрирование элементов?
Заранее благодарю вас
Комментарии:
1. добавьте некоторую часть вашего кода
2. @diegoveloper Я обновил свой пост
Ответ №1:
Если вы не хотите анимировать размер страницы при прокрутке, нет необходимости использовать эту библиотеку каруселей-слайдеров.
Кроме того, PageView
это не лучший Widget
способ добиться желаемого макета, вы должны использовать горизонтальный ListView
с. PageScrollPhysics
import 'package:flutter/material.dart';
class Carousel extends StatelessWidget {
Carousel({
Key key,
@required this.items,
@required this.builderFunction,
@required this.height,
this.dividerIndent = 10,
}) : super(key: key);
final List<dynamic> items;
final double dividerIndent;
final Function(BuildContext context, dynamic item) builderFunction;
final double height;
@override
Widget build(BuildContext context) {
return Container(
height: height,
child: ListView.separated(
physics: PageScrollPhysics(),
separatorBuilder: (context, index) => Divider(
indent: dividerIndent,
),
scrollDirection: Axis.horizontal,
itemCount: items.length,
itemBuilder: (context, index) {
Widget item = builderFunction(context, items[index]);
if (index == 0) {
return Padding(
child: item,
padding: EdgeInsets.only(left: dividerIndent),
);
} else if (index == items.length - 1) {
return Padding(
child: item,
padding: EdgeInsets.only(right: dividerIndent),
);
}
return item;
}),
);
}
}
Использование
Carousel(
height: 150,
items: widget.user.lastGamesPlayed,
builderFunction: (context, item) {
return ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(25)),
child: Container(
width: 200,
color: Theme.MyColors.lightBlue,
child: Center(
child: Padding(
padding: EdgeInsets.all(20),
child: AutoSizeText(
item.name,
style: TextStyle(fontSize: 70),
maxLines: 1,
),
),
),
),
);
},
)
Обновить
Как заметил @AdamK, мое решение не имеет такого же поведения физики прокрутки, как a PageView
, оно больше похоже на горизонтальное ListView
.
Если вы ищете такое поведение разбивки на страницы, вам следует подумать о том, чтобы написать пользовательский ScrollPhysics
и использовать его в своем виджете с возможностью прокрутки.
Это очень хорошо объясненная статья, которая помогает нам достичь желаемого эффекта.
Комментарии:
1. Спасибо за ответ, это определенно на правильном пути, но я попробовал приведенный выше код, и он неправильно перелистывается (страницы неправильно останавливаются после выравнивания первой страницы по левому краю). Я провел некоторый поиск на основе вашего кода, и я нашел эту статью: medium.com/flutter-community/… У которого есть более полное решение (в основном реализация CustomScrollPhysics). Не могли бы вы обновить свое решение, указав ограничения и ссылку на статью в качестве предложения? После этого я проголосую и предоставлю вам награду
2. конечно, @AdamK, рад, что мой ответ вам каким-то образом помог 🙂