285 lines
7.8 KiB
Dart
Raw Normal View History

2019-03-28 00:38:16 +04:00
part of virtual_keyboard;
/// The default keyboard height. Can we overriden by passing
/// `height` argument to `VirtualKeyboard` widget.
const double _virtualKeyboardDefaultHeight = 300;
const int _virtualKeyboardBackspaceEventPerioud = 250;
2019-03-28 00:38:16 +04:00
/// Virtual Keyboard widget.
class VirtualKeyboard extends StatefulWidget {
/// Keyboard Type: Should be inited in creation time.
final VirtualKeyboardType type;
/// Callback for Key press event. Called with pressed `Key` object.
final Function onKeyPress;
/// Virtual keyboard height. Default is 300
final double height;
/// Color for key texts and icons.
final Color textColor;
/// Font size for keyboard keys.
2019-03-28 00:38:16 +04:00
final double fontSize;
/// The builder function will be called for each Key object.
2019-03-28 00:38:16 +04:00
final Widget Function(BuildContext context, VirtualKeyboardKey key) builder;
/// Set to true if you want only to show Caps letters.
final bool alwaysCaps;
2019-03-28 00:38:16 +04:00
VirtualKeyboard(
{Key key,
@required this.type,
2019-03-28 00:38:16 +04:00
@required this.onKeyPress,
this.builder,
this.height = _virtualKeyboardDefaultHeight,
this.textColor = Colors.black,
this.fontSize = 14,
this.alwaysCaps = false})
: super(key: key);
2019-03-28 00:38:16 +04:00
@override
State<StatefulWidget> createState() {
return _VirtualKeyboardState();
2019-03-28 00:38:16 +04:00
}
}
/// Holds the state for Virtual Keyboard class.
class _VirtualKeyboardState extends State<VirtualKeyboard> {
VirtualKeyboardType type;
Function onKeyPress;
2019-03-28 00:38:16 +04:00
// The builder function will be called for each Key object.
Widget Function(BuildContext context, VirtualKeyboardKey key) builder;
double height;
Color textColor;
double fontSize;
bool alwaysCaps;
2019-03-28 00:38:16 +04:00
// Text Style for keys.
TextStyle textStyle;
// True if shift is enabled.
bool isShiftEnabled = false;
@override
void didUpdateWidget(Widget oldWidget) {
super.didUpdateWidget(oldWidget);
setState(() {
type = widget.type;
onKeyPress = widget.onKeyPress;
height = widget.height;
textColor = widget.textColor;
fontSize = widget.fontSize;
alwaysCaps = widget.alwaysCaps;
// Init the Text Style for keys.
textStyle = TextStyle(
fontSize: fontSize,
color: textColor,
);
});
}
2019-03-28 00:38:16 +04:00
@override
void initState() {
super.initState();
type = widget.type;
onKeyPress = widget.onKeyPress;
height = widget.height;
textColor = widget.textColor;
fontSize = widget.fontSize;
alwaysCaps = widget.alwaysCaps;
2019-03-28 00:38:16 +04:00
// Init the Text Style for keys.
textStyle = TextStyle(
fontSize: fontSize,
color: textColor,
);
}
@override
Widget build(BuildContext context) {
return type == VirtualKeyboardType.Numeric ? _numeric() : _alphanumeric();
}
Widget _alphanumeric() {
return Container(
height: height,
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: _rows(),
),
);
}
Widget _numeric() {
return Container(
height: height,
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: _rows(),
),
);
}
/// Returns the rows for keyboard.
List<Widget> _rows() {
// Get the keyboard Rows
List<List<VirtualKeyboardKey>> keyboardRows =
type == VirtualKeyboardType.Numeric
? _getKeyboardRowsNumeric()
: _getKeyboardRows();
// Generate keyboard row.
List<Widget> rows = List.generate(keyboardRows.length, (int rowNum) {
return Material(
color: Colors.transparent,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
// Generate keboard keys
children: List.generate(
keyboardRows[rowNum].length,
(int keyNum) {
// Get the VirtualKeyboardKey object.
VirtualKeyboardKey virtualKeyboardKey =
keyboardRows[rowNum][keyNum];
Widget keyWidget;
// Check if builder is specified.
// Call builder function if specified or use default
// Key widgets if not.
if (builder == null) {
// Check the key type.
switch (virtualKeyboardKey.keyType) {
case VirtualKeyboardKeyType.String:
// Draw String key.
keyWidget = _keyboardDefaultKey(virtualKeyboardKey);
break;
case VirtualKeyboardKeyType.Action:
// Draw action key.
keyWidget = _keyboardDefaultActionKey(virtualKeyboardKey);
break;
}
} else {
// Call the builder function, so the user can specify custom UI for keys.
keyWidget = builder(context, virtualKeyboardKey);
if (keyWidget == null) {
throw 'builder function must return Widget';
}
}
return keyWidget;
},
),
),
);
});
return rows;
}
2019-04-02 15:56:51 +04:00
// True if long press is enabled.
bool longPress;
2019-03-28 00:38:16 +04:00
/// Creates default UI element for keyboard Key.
Widget _keyboardDefaultKey(VirtualKeyboardKey key) {
return Expanded(
child: InkWell(
onTap: () {
onKeyPress(key);
},
child: Container(
height: height / _keyRows.length,
child: Center(
child: Text(
alwaysCaps
? key.capsText
: (isShiftEnabled ? key.capsText : key.text),
2019-03-28 00:38:16 +04:00
style: textStyle,
)),
),
));
}
/// Creates default UI element for keyboard Action Key.
Widget _keyboardDefaultActionKey(VirtualKeyboardKey key) {
// Holds the action key widget.
Widget actionKey;
// Switch the action type to build action Key widget.
switch (key.action) {
case VirtualKeyboardKeyAction.Backspace:
actionKey = GestureDetector(
2019-04-02 16:39:23 +04:00
onLongPress: () {
longPress = true;
// Start sending backspace key events while longPress is true
Timer.periodic(
Duration(milliseconds: _virtualKeyboardBackspaceEventPerioud),
(timer) {
if (longPress) {
onKeyPress(key);
} else {
// Cancel timer.
timer.cancel();
}
});
},
onLongPressUp: () {
// Cancel event loop
longPress = false;
},
child: Container(
height: double.infinity,
width: double.infinity,
child: Icon(
Icons.backspace,
color: textColor,
),
));
2019-03-28 00:38:16 +04:00
break;
case VirtualKeyboardKeyAction.Shift:
actionKey = Icon(Icons.arrow_upward, color: textColor);
break;
case VirtualKeyboardKeyAction.Space:
actionKey = actionKey = Icon(Icons.space_bar, color: textColor);
break;
case VirtualKeyboardKeyAction.Return:
actionKey = Icon(
Icons.keyboard_return,
color: textColor,
);
break;
}
return Expanded(
child: InkWell(
onTap: () {
2019-04-02 16:39:23 +04:00
if (key.action == VirtualKeyboardKeyAction.Shift) {
if (!alwaysCaps) {
setState(() {
isShiftEnabled = !isShiftEnabled;
});
}
}
2019-04-02 16:39:23 +04:00
onKeyPress(key);
2019-03-28 00:38:16 +04:00
},
child: Container(
2019-04-02 16:39:23 +04:00
alignment: Alignment.center,
2019-03-28 00:38:16 +04:00
height: height / _keyRows.length,
2019-04-02 16:39:23 +04:00
child: actionKey,
2019-03-28 00:38:16 +04:00
),
),
);
}
}