#ルーレットアプリをつくってみた
今回はシンプルなルーレットアプリを作ってみました。パッケージを参照しただけで完成したので共有します。新しい機能をつければ面白いアプリになると思います。
#使用したパッケージ
flutter_spinning_wheel 1.1.0
#準備する
画像参照元: 画像をダウンロードする
##使用パッケージを宣言する
pubspec.yaml
dependencies:
flutter_spinning_wheel: ^1.1.0
##assets/imagesの画像を宣言する
pubspec.yaml
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
assets:
- assets/images/wheel-6-300.png
- assets/images/roulette-8-300.png
#コードを書いてみよう
main.dart
import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_spinning_wheel/flutter_spinning_wheel.dart';
void main() {
SystemChrome.setEnabledSystemUIOverlays([]);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: Container(
color: Color(0xffB0F9D2),
child: InkWell(
child: Center(child: Text('B A S I C')),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Basic()),
);
}),
),
),
Expanded(
child: Container(
color: Color(0xffDDC3FF),
child: InkWell(
child: Center(child: Text('R O U L E T T E')),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Roulette()),
);
}),
),
),
],
),
);
}
Widget buildNavigationButton({String text, Function onPressedFn}) {
return FlatButton(
color: Color.fromRGBO(255, 255, 255, 0.3),
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50.0),
),
onPressed: onPressedFn,
child: Text(
text,
style: TextStyle(color: Colors.white, fontSize: 18.0),
),
);
}
}
class Basic extends StatelessWidget {
final StreamController _dividerController = StreamController<int>();
dispose() {
_dividerController.close();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(backgroundColor: Color(0xffB0F9D2), elevation: 0.0),
backgroundColor: Color(0xffB0F9D2),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SpinningWheel(
Image.asset('assets/images/wheel-6-300.png'),
width: 310,
height: 310,
initialSpinAngle: _generateRandomAngle(),
spinResistance: 0.2,
dividers: 6,
onUpdate: _dividerController.add,
onEnd: _dividerController.add,
),
StreamBuilder(
stream: _dividerController.stream,
builder: (context, snapshot) =>
snapshot.hasData ? BasicScore(snapshot.data) : Container(),
)
],
),
),
);
}
double _generateRandomAngle() => Random().nextDouble() * pi * 2;
}
class BasicScore extends StatelessWidget {
final int selected;
final Map<int, String> labels = {
1: 'Purple',
2: 'Magenta',
3: 'Red',
4: 'Dark Orange',
5: 'Light Orange',
6: 'Yellow',
};
BasicScore(this.selected);
@override
Widget build(BuildContext context) {
return Text('${labels[selected]}',
style: TextStyle(fontStyle: FontStyle.italic));
}
}
class Roulette extends StatelessWidget {
final StreamController _dividerController = StreamController<int>();
final _wheelNotifier = StreamController<double>();
dispose() {
_dividerController.close();
_wheelNotifier.close();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(backgroundColor: Color(0xffDDC3FF), elevation: 0.0),
backgroundColor: Color(0xffDDC3FF),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SpinningWheel(
Image.asset('assets/images/roulette-8-300.png'),
width: 310,
height: 310,
initialSpinAngle: _generateRandomAngle(),
spinResistance: 0.6,
canInteractWhileSpinning: false,
dividers: 8,
onUpdate: _dividerController.add,
onEnd: _dividerController.add,
secondaryImage:
Image.asset('assets/images/roulette-center-300.png'),
secondaryImageHeight: 110,
secondaryImageWidth: 110,
shouldStartOrStop: _wheelNotifier.stream,
),
SizedBox(height: 30),
StreamBuilder(
stream: _dividerController.stream,
builder: (context, snapshot) =>
snapshot.hasData ? RouletteScore(snapshot.data) : Container(),
),
SizedBox(height: 30),
new RaisedButton(
child: new Text("Start"),
onPressed: () =>
_wheelNotifier.sink.add(_generateRandomVelocity()),
)
],
),
),
);
}
double _generateRandomVelocity() => (Random().nextDouble() * 6000) + 2000;
double _generateRandomAngle() => Random().nextDouble() * pi * 2;
}
class RouletteScore extends StatelessWidget {
final int selected;
final Map<int, String> labels = {
1: '1000\$',
2: '400\$',
3: '800\$',
4: '7000\$',
5: '5000\$',
6: '300\$',
7: '2000\$',
8: '100\$',
};
RouletteScore(this.selected);
@override
Widget build(BuildContext context) {
return Text('${labels[selected]}',
style: TextStyle(fontStyle: FontStyle.italic, fontSize: 24.0));
}
}
#まとめ
今回はシンプルなパッケージを参照して導入までを紹介しました。次回はこの機能を応用して新しいアプリを作りたいと思います。
#参照元
参照コード
#Flutter関連記事
Flutter 入門 -textFieldを開いたときにkeyboardを表示しない-
Flutterでtodo Listを作ってみた -初心者必見-
flutterでQRコードリーダーを作ってみた
カレンダーを使用して日付を指定する flutter