238 lines
6.4 KiB
Dart
238 lines
6.4 KiB
Dart
|
part of virtual_keyboard;
|
||
|
|
||
|
|
||
|
|
||
|
/// The default keyboard height. Can we overriden by passing
|
||
|
/// `height` argument to `VirtualKeyboard` widget.
|
||
|
const double _virtualKeyboardDefaultHeight = 300;
|
||
|
|
||
|
/// 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.
|
||
|
final double fontSize;
|
||
|
|
||
|
// The builder function will be called for each Key object.
|
||
|
final Widget Function(BuildContext context, VirtualKeyboardKey key) builder;
|
||
|
|
||
|
VirtualKeyboard(
|
||
|
{@required this.type,
|
||
|
@required this.onKeyPress,
|
||
|
this.builder,
|
||
|
this.height = _virtualKeyboardDefaultHeight,
|
||
|
this.textColor = Colors.black,
|
||
|
this.fontSize = 14});
|
||
|
|
||
|
@override
|
||
|
State<StatefulWidget> createState() {
|
||
|
return _VirtualKeyboardState(
|
||
|
type: type,
|
||
|
onKeyPress: onKeyPress,
|
||
|
builder: builder,
|
||
|
height: height,
|
||
|
textColor: textColor,
|
||
|
fontSize: fontSize);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Holds the state for Virtual Keyboard class.
|
||
|
class _VirtualKeyboardState extends State<VirtualKeyboard> {
|
||
|
final VirtualKeyboardType type;
|
||
|
final Function onKeyPress;
|
||
|
// The builder function will be called for each Key object.
|
||
|
final Widget Function(BuildContext context, VirtualKeyboardKey key) builder;
|
||
|
final double height;
|
||
|
final Color textColor;
|
||
|
final double fontSize;
|
||
|
|
||
|
_VirtualKeyboardState(
|
||
|
{this.type,
|
||
|
this.onKeyPress,
|
||
|
this.height,
|
||
|
this.builder,
|
||
|
this.textColor,
|
||
|
this.fontSize});
|
||
|
|
||
|
// Text Style for keys.
|
||
|
TextStyle textStyle;
|
||
|
|
||
|
// True if shift is enabled.
|
||
|
bool isShiftEnabled = false;
|
||
|
|
||
|
@override
|
||
|
void initState() {
|
||
|
super.initState();
|
||
|
|
||
|
// 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;
|
||
|
}
|
||
|
|
||
|
/// 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(
|
||
|
isShiftEnabled ? key.capsText : key.text,
|
||
|
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 = Icon(
|
||
|
Icons.backspace,
|
||
|
color: textColor,
|
||
|
);
|
||
|
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: () {
|
||
|
if (key.action == VirtualKeyboardKeyAction.Shift) {
|
||
|
setState(() {
|
||
|
isShiftEnabled = !isShiftEnabled;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
onKeyPress(key);
|
||
|
},
|
||
|
child: Container(
|
||
|
height: height / _keyRows.length,
|
||
|
child: Center(
|
||
|
child: actionKey,
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
);
|
||
|
}
|
||
|
}
|