import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
title: 'Tracking Sample',
debugShowCheckedModeBanner: false,
theme: ThemeData.dark().copyWith(
primaryColor: Color(0xFF0D2336),
scaffoldBackgroundColor: Color(0xFF12314A),
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage();
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Percentage calculation'),
),
body: const TrackingSample(),
);
}
}
class TrackingSample extends StatefulWidget {
const TrackingSample({Key key}) : super(key: key);
_TrackingSampleState createState() => _TrackingSampleState();
}
class _TrackingSampleState extends State<TrackingSample> {
// デバッグ用
String _position = 'Try the drag.';
// GlobalKeyを用意
final _globalKey = GlobalKey();
// Widgetのサイズ格納用の変数
Size _widgetSize;
void initState() {
super.initState();
// GlobalKeyのContextからSizeを取得
WidgetsBinding.instance.addPostFrameCallback((_) {
_widgetSize = _globalKey.currentContext.size;
});
}
// ドラッグ位置の割合を計算する
Offset _calcPercentage(Offset dragPosition, Size widgetSize) {
// x軸の割合
final x = dragPosition.dx / widgetSize.width;
// y軸の割合
final y = dragPosition.dy / widgetSize.height;
return Offset(x, y);
}
Widget build(BuildContext context) {
return Stack(
children: [
// アニメーション表示用Widget
Center(
child: SizedBox(
height: 120,
width: 120,
// 後ほどアニメーションに置き換える
child: Placeholder(),
),
),
// デバッグ用
Center(child: Text(_position)),
// ドラッグ位置取得用Widget
GestureDetector(
onPanDown: (detail) {
// 初回画面タップ時に一度だけ呼び出される
// トラッキングに使用
final percentage = _calcPercentage(
detail.localPosition,
_widgetSize,
);
setState(
() => _position = 'onPanDown: $percentage',
);
},
onPanUpdate: (detail) {
// ドラッグ位置が変化するたびに呼び出される
// トラッキングに使用
final percentage = _calcPercentage(
detail.localPosition,
_widgetSize,
);
setState(
() => _position = 'onPanUpdate: $percentage',
);
},
onPanEnd: (detail) {
// ドラッグ終了時に呼び出される
// トラッキングを終了し、アニメーションの初期化に使用
setState(
() => _position = 'onPanEnd',
);
},
child: Container(
key: _globalKey,
color: Colors.transparent,
),
),
],
);
}
}
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.