![](/img/trans.png)
[英]Flutter: combining Draggable and GestureDetector in a Stack of widgets
[英]Flutter - Draggable AND Scaling Widgets
所以對於這個應用程序(Windows,Web)我有兩個要求:
對於 (1) 我使用了這個答案。 對於 (2) 我使用了這個解決方案。
正如下面的代碼注釋中提到的,我不能同時擁有:
如果我根據窗口大小動態設置logicWidth
和logicHeight
,則拖動工作正常,但可拖動的小部件不會縮放,而是保持相同的大小,而不管窗口大小如何。
如果我將logicWidth
和logicHeight
設置為一個常量值(當前cleanHeight
的值),對於其他屏幕尺寸,拖動將被弄亂,但可拖動的小部件將隨窗口尺寸正確縮放。
換句話說:為了使拖動能夠很好地工作,這些值需要隨時與窗口大小相匹配。 但是通過更改這些值,我破壞了我需要的縮放比例。
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:matrix_gesture_detector/matrix_gesture_detector.dart';
//containing widgets to drag around
const List<Widget> draggableWidgets = [
DraggableWidget(
draggableWidget: CircleAvatar(
backgroundColor: Colors.green,
radius: 32,
)),
DraggableWidget(
draggableWidget: CircleAvatar(
backgroundColor: Colors.red,
radius: 24,
)),
];
class FrontPageWidget extends ConsumerWidget {
const FrontPageWidget({Key? key}) : super(key: key);
static const routeName = '/frontPage';
@override
Widget build(BuildContext context, WidgetRef ref) {
//screen height and padding
final height = MediaQuery.of(context).size.height;
final padding = MediaQuery.of(context).viewPadding;
// Height (without status and toolbar)
final cleanHeight = height - padding.top - kToolbarHeight;
//either make those values dynamic (cleanHeight updates depending on screen size / window size) OR constant (961px is the cleanHeight on full screen)
//if values are dynamic => the draggable widgets not scaling to screen size BUT dragging works fine
//if values are constant => the draggable widgets do scale to screen size BUT dragging is messed
final logicWidth = cleanHeight; //961
final logicHeight = cleanHeight; //961
return Scaffold(
appBar: AppBar(
title: const Text('Main Page'),
),
body: SizedBox.expand(
child: FittedBox(
fit: BoxFit.contain,
alignment: Alignment.center,
child: Container(
color: Colors.grey,
width: logicWidth,
height: logicHeight,
child: Stack(
children: draggableWidgets,
),
))),
);
}
}
class DraggableWidget extends StatelessWidget {
final Widget draggableWidget;
const DraggableWidget({Key? key, required this.draggableWidget})
: super(key: key);
@override
Widget build(BuildContext context) {
final ValueNotifier<Matrix4> notifier = ValueNotifier(Matrix4.identity());
return Center(
child: MatrixGestureDetector(
onMatrixUpdate: (m, tm, sm, rm) {
notifier.value = m;
},
child: AnimatedBuilder(
animation: notifier,
builder: (ctx, child) {
return Transform(
transform: notifier.value,
child: Center(
child: Stack(
children: [draggableWidget],
),
),
);
},
),
),
);
}
}
一種方法是將draggableWidget
包裝在Transform
小部件中,並設置與尺寸相關的scale
因子:
child: AnimatedBuilder(
animation: notifier,
builder: (ctx, child) {
final height = MediaQuery.of(context).size.height;
return Transform(
transform: notifier.value,
child: Center(
child: Stack(
children: [
Transform.scale(
scale: height / 1000,
child: draggableWidget)
],
),
),
);
},
),
我有一個類似的問題,而不是從 MediaQuery 獲取高度,而是從 LayoutBuilder 獲取高度,我注意到它在調整窗口大小時工作得更好。
body: LayoutBuilder(
builder: (context, constraints) {
return SizedBox.expand(
child: FittedBox(
fit: BoxFit.contain,
alignment: Alignment.center,
child: Container(
color: Colors.grey,
width: constraints.maxWidth,
height: constraints.maxHeight,
child: Stack(
children: draggableWidgets,
),
)
)
);
}
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.