Как анимировать draggableScrollableSheet и его содержимое во флаттере?IOS

Программируем под IOS
Ответить
Anonymous
 Как анимировать draggableScrollableSheet и его содержимое во флаттере?

Сообщение Anonymous »


Изображение

Я пытаюсь эмулировать этот нижний лист из приложения «Найти мой» на iOS.
Я использовал draggableScrollableSheet, но он работает не так хорошо, как тот, который находится в «Найти мой». .

Код: Выделить всё

class DraggableSheet extends StatefulWidget {
final Widget child;
final String title;
const DraggableSheet({super.key, required this.child, required this.title});

@override
State createState() => _DraggableSheetState();
}

class _DraggableSheetState extends State {
final sheet = GlobalKey();
final controller = DraggableScrollableController();

@override
void initState() {
super.initState();
controller.addListener(onChanged);
}

void onChanged() {
final currentSize = controller.size;
if (currentSize  animateSheet(getSheet.snapSizes!.first);

void anchor() => animateSheet(getSheet.snapSizes!.last);

void expand() => animateSheet(getSheet.maxChildSize);

void hide() => animateSheet(getSheet.minChildSize);

void animateSheet(double size) {
controller.animateTo(
size,
duration: const Duration(milliseconds: 100),
curve: Curves.easeIn,
);
}

@override
void dispose() {
super.dispose();
controller.dispose();
}

DraggableScrollableSheet get getSheet =>
(sheet.currentWidget as DraggableScrollableSheet);

@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, constraints) {
return DraggableScrollableSheet(
key: sheet,
snapAnimationDuration: const Duration(milliseconds: 100),
initialChildSize: 0.157,
maxChildSize: 0.93,
minChildSize: 0,
expand: true,
snap: true,
snapSizes: const [
0.157,
0.4,
0.93,
],
controller: controller,
builder: (BuildContext context, ScrollController scrollController) {
return DecoratedBox(
decoration: BoxDecoration(
color: CupertinoTheme.of(context).scaffoldBackgroundColor,
boxShadow: const [
BoxShadow(
color: Colors.black12,
blurRadius: 10,
spreadRadius: 1,
offset: Offset(0, 1),
),
],
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
),
child: CustomScrollView(
controller: scrollController,
slivers: [
BottomSheetHeader(title: widget.title),
SliverToBoxAdapter(
child: widget.child,
),
],
),
);
},
);
});
}
}

В нем отсутствует анимация привязки отскока, и я не мог понять, как они отображают такие кнопки, как «Добавить элементы», при первом щелчке (до ~ половины экрана), а затем разворачиваются. от корпуса (оставляя кнопки внизу).

Код: Выделить всё

BottomSheetHeader

Код: Выделить всё

class BottomSheetHeader extends StatelessWidget {
final String title;
const BottomSheetHeader({super.key, required this.title});

@override
Widget build(BuildContext context) {
return SliverPersistentHeader(
pinned: true,
delegate: SliverAppBarDelegate(
minHeight: 52,
maxHeight: 52,
child: Container(
decoration: BoxDecoration(
color: CupertinoTheme.of(context).scaffoldBackgroundColor,
),
child: Column(
children: [
Center(
child: Wrap(
children: [
Container(
width: 36,
margin: const EdgeInsets.only(top: 4, bottom: 4),
height: 5,
decoration: const BoxDecoration(
color: Colors.black26,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
),
],
),
),
Row(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: Text(
title,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
],
),
const SizedBox(height: 8.0),
const Divider(
height: 0,
),
],
),
),
),
);
}
}

class SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
SliverAppBarDelegate({
required this.minHeight,
required this.maxHeight,
required this.child,
});
final double minHeight;
final double maxHeight;
final Widget child;

@override
double get minExtent => minHeight;
@override
double get maxExtent => max(maxHeight, minHeight);

@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return SizedBox.expand(child: child);
}

@override
bool shouldRebuild(SliverAppBarDelegate oldDelegate) {
return maxHeight != oldDelegate.maxHeight ||
minHeight != oldDelegate.minHeight ||
child != oldDelegate.child;
}
}

Есть ли лучший способ сделать это?


Подробнее здесь: https://stackoverflow.com/questions/785 ... in-flutter
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»