Open7
Flutter開発を楽にするコピペで完結スクラップ🚀
ピン留めされたアイテム
このスクラップについて
なるべくコピペだけですぐに使えるものをメモとして残すスクラップになります。
新規プロジェクトを始めるときに使えそうなものをピックアップできれば。
BlurButton
Widget _submitButton() {
return Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.symmetric(vertical: 15),
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.grey.shade200,
offset: Offset(2, 4),
blurRadius: 5,
spreadRadius: 2)
],
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [Color(0xfffbb448), Color(0xfff7892b)])),
child: Text(
'Login',
style: TextStyle(fontSize: 20, color: Colors.white),
),
);
}
BottomNavigationでRebuildを発生させない
final List<Widget> _widgetOptions = <Widget>[
OnePage(),
TwoPage(),
ThreePage(),
FourPage(),
];
Widget build(BuildContext context) {
debugPrint('RootPage build');
var brightness = MediaQuery.of(context).platformBrightness;
return Scaffold(
body: _widgetOptions.elementAt(_selectedIndex),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[...],
currentIndex: _selectedIndex,
onTap: _onItemTapped,
),
);
}
// body: _widgetOptions.elementAt(_selectedIndex),
// bodyをIndexedStackに変更
body: IndexedStack(
index: _selectedIndex,
children: _widgetOptions,
),
バリデーションつきTextForm コピペ用
FormTextField
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class FormTextField extends StatelessWidget {
FormTextField({
this.hintText,
this.maxLength,
this.validator,
this.formKey,
this.textInputAction,
this.onFieldSubmitted,
this.focusNode,
this.isAutoFocus = false,
this.controller,
this.title,
this.initValue,
this.isNumberOnly,
this.callback});
final String title;
final String initValue;
final String hintText;
final int maxLength;
final bool isNumberOnly;
final Function(String) validator;
final Function(String) callback;
final Function(String) onFieldSubmitted;
final GlobalKey<FormState> formKey;
final TextInputAction textInputAction;
final FocusNode focusNode;
final bool isAutoFocus;
final TextEditingController controller;
Widget _entryField(BuildContext context) {
var brightness = MediaQuery.of(context).platformBrightness;
return Container(
margin: EdgeInsets.symmetric(vertical: 4),
child: Form(
key: formKey,
child: TextFormField(
initialValue: initValue,
maxLength: maxLength,
controller: controller,
autofocus: isAutoFocus,
focusNode: focusNode,
style: Theme.of(context).textTheme.headline5,
keyboardType: isNumberOnly ? TextInputType.number : TextInputType.text,
textInputAction: textInputAction,
inputFormatters: isNumberOnly ? [
// WhitelistingTextInputFormatter.digitsOnly,
FilteringTextInputFormatter.digitsOnly,
] : null,
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(vertical: 0.0, horizontal: 16),
counterStyle: Theme.of(context).textTheme.subtitle2,
hintText: title,
errorStyle: Theme.of(context).textTheme.subtitle2
.merge(SavingMoneyTextTheme.font_color_error),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(4),
borderSide: BorderSide(
width: 0.25,
color: Colors.red,
),
),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(4),
borderSide: BorderSide(
width: 0.25,
color: Colors.red,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
width: 0.25,
color: (brightness == Brightness.light) ? kDarkPrimaryGreyColor : kPrimaryTextColor,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
width: 0.25,
color: (brightness == Brightness.light) ? kDarkPrimaryGreyColor : kPrimaryTextColor,
),
),
fillColor: (brightness == Brightness.light) ? Colors.white : kDarkSecondaryBackgroundColor,
filled: true),
validator: validator,
onFieldSubmitted: onFieldSubmitted,
onChanged: callback,
),
),
);
}
Widget build(BuildContext context) {
return _entryField(context);
}
}
呼び出し
FormTextField(
formKey: _formMoneyValueKey,
title: Localized.of(context).value,
hintText: Localized.of(context).presetValueHint,
textInputAction: TextInputAction.next,
isNumberOnly: true,
isAutoFocus: false,
focusNode: moneyTitleFocus,
controller: _valueController,
validator: (value) {
if (value.isEmpty || value == '0') {
// 任意のエラーメッセージ
return Localized.of(context).addMoneyErrorValue;
} else {
return null;
}
},
callback: (value) {
print(value);
},
onFieldSubmitted: (v) {
FocusScope.of(context).requestFocus(focus);
},
),
Flutter Web を想定したマウスカーソル対応 (Card)
MouseRegionでラップしてあげるだけで良い。
onHoverやonExit、onEnterなどマウスカーソルの検知ができる。
class CardCell extends StatefulWidget {
final String title;
final String subtitle;
CardCell({
this.title,
this.subtitle,
});
@override
_CardCellState createState() => _CardCellState();
}
class _CardCellState extends State<CardCell> {
bool _isHover = false;
@override
Widget build(BuildContext context) {
return MouseRegion(
cursor: SystemMouseCursors.click,
onHover: (_) {
setState(() {
_isHover = true;
});
},
onExit: (_) {
setState(() {
_isHover = false;
});
},
onEnter: (_) {
setState(() {
_isHover = true;
});
},
child: Card(
elevation: _isHover ? 2 : 0,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: ListTile(
title: Text(
widget.title,
style: TextStyle(
fontSize: 18,
color: _isHover ? Colors.blueAccent : Colors.black,
fontWeight: _isHover ? FontWeight.bold : FontWeight.w500,
),
),
subtitle: Text(
widget.subtitle,
maxLines: 3,
),
),
),
),
);
}
}
参考
Circle Icon Sample
Rounded Icon with Text View