null safety support

This commit is contained in:
Ahmed 2022-07-06 09:31:02 +02:00
parent 143bedc6ac
commit 1d363db57d
8 changed files with 155 additions and 147 deletions

1
.gitignore vendored
View File

@ -18,6 +18,7 @@
# Visual Studio Code related # Visual Studio Code related
.vscode/ .vscode/
.vs/
# Flutter/Dart/Pub related # Flutter/Dart/Pub related
**/doc/api/ **/doc/api/

View File

@ -21,4 +21,12 @@
## [0.2.2] - 19/03/2020. ## [0.2.2] - 19/03/2020.
* Adding multi-language support. * Adding multi-language support.
* Customizable layout. * Customizable layout.
## [0.2.4] - 19/03/2020.
* Adding missing chars (ز-ج).
## [1.0.1] - 06/07/2022.
* null safety

View File

@ -1,10 +1,13 @@
#!/bin/sh #!/bin/sh
# This is a generated file; do not edit or check into version control. # This is a generated file; do not edit or check into version control.
export "FLUTTER_ROOT=C:\src\flutter" export "FLUTTER_ROOT=C:\Flutter\flutter"
export "FLUTTER_APPLICATION_PATH=D:\_Workspace\virtual_keyboard_multi_language\example" export "FLUTTER_APPLICATION_PATH=C:\Workspace\virtual_keyboard_multi_language\example"
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
export "FLUTTER_TARGET=lib\main.dart" export "FLUTTER_TARGET=lib\main.dart"
export "FLUTTER_BUILD_DIR=build" export "FLUTTER_BUILD_DIR=build"
export "SYMROOT=${SOURCE_ROOT}/../build\ios"
export "FLUTTER_FRAMEWORK_DIR=C:\src\flutter\bin\cache\artifacts\engine\ios"
export "FLUTTER_BUILD_NAME=1.0.0" export "FLUTTER_BUILD_NAME=1.0.0"
export "FLUTTER_BUILD_NUMBER=1" export "FLUTTER_BUILD_NUMBER=1"
export "DART_OBFUSCATION=false"
export "TRACK_WIDGET_CREATION=false"
export "TREE_SHAKE_ICONS=false"
export "PACKAGE_CONFIG=.dart_tool/package_config.json"

View File

@ -1,6 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:virtual_keyboard_multi_language/virtual_keyboard_multi_language.dart'; import 'package:virtual_keyboard_multi_language/virtual_keyboard_multi_language.dart';
import 'package:example/custom_layout.dart';
void main() => runApp(MyApp()); void main() => runApp(MyApp());
@ -28,7 +27,7 @@ class MyHomePage extends StatefulWidget {
class _MyHomePageState extends State<MyHomePage> { class _MyHomePageState extends State<MyHomePage> {
// Holds the text that user typed. // Holds the text that user typed.
String text = ''; String text = '';
CustomLayoutKeys _customLayoutKeys; // CustomLayoutKeys _customLayoutKeys;
// True if shift enabled. // True if shift enabled.
bool shiftEnabled = false; bool shiftEnabled = false;
@ -39,7 +38,7 @@ class _MyHomePageState extends State<MyHomePage> {
@override @override
void initState() { void initState() {
_customLayoutKeys = CustomLayoutKeys(); // _customLayoutKeys = CustomLayoutKeys();
_controllerText = TextEditingController(); _controllerText = TextEditingController();
super.initState(); super.initState();
} }
@ -55,7 +54,7 @@ class _MyHomePageState extends State<MyHomePage> {
children: <Widget>[ children: <Widget>[
Text( Text(
text, text,
style: Theme.of(context).textTheme.display1, style: Theme.of(context).textTheme.bodyText1,
), ),
Text( Text(
_controllerText.text, _controllerText.text,
@ -85,8 +84,11 @@ class _MyHomePageState extends State<MyHomePage> {
//width: 500, //width: 500,
textColor: Colors.white, textColor: Colors.white,
textController: _controllerText, textController: _controllerText,
//customLayoutKeys: _customLayoutKeys, //customLayoutKeys: _customLayoutKeys,
defaultLayouts: [VirtualKeyboardDefaultLayouts.Arabic,VirtualKeyboardDefaultLayouts.English], defaultLayouts: [
VirtualKeyboardDefaultLayouts.Arabic,
VirtualKeyboardDefaultLayouts.English
],
//reverseLayout :true, //reverseLayout :true,
type: isNumericMode type: isNumericMode
? VirtualKeyboardType.Numeric ? VirtualKeyboardType.Numeric

View File

@ -2,19 +2,22 @@ part of virtual_keyboard_multi_language;
/// Virtual Keyboard key /// Virtual Keyboard key
class VirtualKeyboardKey { class VirtualKeyboardKey {
String text; String? text;
String capsText; String? capsText;
final VirtualKeyboardKeyType keyType; final VirtualKeyboardKeyType keyType;
final VirtualKeyboardKeyAction action; final VirtualKeyboardKeyAction? action;
VirtualKeyboardKey( VirtualKeyboardKey(
{this.text, this.capsText, @required this.keyType, this.action}){ {this.text, this.capsText, required this.keyType, this.action}) {
if (this.text == null && this.action != null) {
if(this.text == null && this.action != null){ this.text = action == VirtualKeyboardKeyAction.Space
this.text = action == VirtualKeyboardKeyAction.Space ? ' ' : (action == VirtualKeyboardKeyAction.Return ? '\n' : ''); ? ' '
} : (action == VirtualKeyboardKeyAction.Return ? '\n' : '');
if(this.capsText == null && this.action != null){ }
this.capsText = action == VirtualKeyboardKeyAction.Space ? ' ' : (action == VirtualKeyboardKeyAction.Return ? '\n' : ''); if (this.capsText == null && this.action != null) {
} this.capsText = action == VirtualKeyboardKeyAction.Space
} ? ' '
: (action == VirtualKeyboardKeyAction.Return ? '\n' : '');
}
}
} }

View File

@ -12,28 +12,28 @@ class VirtualKeyboard extends StatefulWidget {
final VirtualKeyboardType type; final VirtualKeyboardType type;
/// Callback for Key press event. Called with pressed `Key` object. /// Callback for Key press event. Called with pressed `Key` object.
final Function onKeyPress; final Function? onKeyPress;
/// Virtual keyboard height. Default is 300 /// Virtual keyboard height. Default is 300
final double height; final double height;
/// Virtual keyboard height. Default is full screen width /// Virtual keyboard height. Default is full screen width
final double width; final double? width;
/// Color for key texts and icons. /// Color for key texts and icons.
final Color textColor; final Color textColor;
/// Font size for keyboard keys. /// Font size for keyboard keys.
final double fontSize; final double fontSize;
/// the custom layout for multi or single language /// the custom layout for multi or single language
final VirtualKeyboardLayoutKeys customLayoutKeys; final VirtualKeyboardLayoutKeys? customLayoutKeys;
/// the text controller go get the output and send the default input /// the text controller go get the output and send the default input
final TextEditingController textController; final TextEditingController? textController;
/// The builder function will be called for each Key object. /// The builder function will be called for each Key object.
final Widget Function(BuildContext context, VirtualKeyboardKey key) builder; final Widget Function(BuildContext context, VirtualKeyboardKey key)? builder;
/// Set to true if you want only to show Caps letters. /// Set to true if you want only to show Caps letters.
final bool alwaysCaps; final bool alwaysCaps;
@ -43,11 +43,11 @@ class VirtualKeyboard extends StatefulWidget {
/// used for multi-languages with default layouts, the default is English only /// used for multi-languages with default layouts, the default is English only
/// will be ignored if customLayoutKeys is not null /// will be ignored if customLayoutKeys is not null
final List<VirtualKeyboardDefaultLayouts> defaultLayouts; final List<VirtualKeyboardDefaultLayouts>? defaultLayouts;
VirtualKeyboard( VirtualKeyboard(
{Key key, {Key? key,
@required this.type, required this.type,
this.onKeyPress, this.onKeyPress,
this.builder, this.builder,
this.width, this.width,
@ -69,39 +69,39 @@ class VirtualKeyboard extends StatefulWidget {
/// Holds the state for Virtual Keyboard class. /// Holds the state for Virtual Keyboard class.
class _VirtualKeyboardState extends State<VirtualKeyboard> { class _VirtualKeyboardState extends State<VirtualKeyboard> {
VirtualKeyboardType type; late VirtualKeyboardType type;
Function onKeyPress; Function? onKeyPress;
TextEditingController textController; late TextEditingController textController;
// The builder function will be called for each Key object. // The builder function will be called for each Key object.
Widget Function(BuildContext context, VirtualKeyboardKey key) builder; Widget Function(BuildContext context, VirtualKeyboardKey key)? builder;
double height; late double height;
double width; double? width;
Color textColor; late Color textColor;
double fontSize; late double fontSize;
bool alwaysCaps; late bool alwaysCaps;
bool reverseLayout; late bool reverseLayout;
VirtualKeyboardLayoutKeys customLayoutKeys; late VirtualKeyboardLayoutKeys customLayoutKeys;
// Text Style for keys. // Text Style for keys.
TextStyle textStyle; late TextStyle textStyle;
// True if shift is enabled. // True if shift is enabled.
bool isShiftEnabled = false; bool isShiftEnabled = false;
void _onKeyPress(VirtualKeyboardKey key){ void _onKeyPress(VirtualKeyboardKey key) {
if (key.keyType == VirtualKeyboardKeyType.String) { if (key.keyType == VirtualKeyboardKeyType.String) {
textController.text += (isShiftEnabled ? key.capsText : key.text); textController.text += ((isShiftEnabled ? key.capsText : key.text) ?? '');
} else if (key.keyType == VirtualKeyboardKeyType.Action) { } else if (key.keyType == VirtualKeyboardKeyType.Action) {
switch (key.action) { switch (key.action) {
case VirtualKeyboardKeyAction.Backspace: case VirtualKeyboardKeyAction.Backspace:
if (textController.text.length == 0) return; if (textController.text.length == 0) return;
textController.text = textController.text.substring(0, textController.text.length - 1); textController.text =
textController.text.substring(0, textController.text.length - 1);
break; break;
case VirtualKeyboardKeyAction.Return: case VirtualKeyboardKeyAction.Return:
textController.text += '\n'; textController.text += '\n';
break; break;
case VirtualKeyboardKeyAction.Space: case VirtualKeyboardKeyAction.Space:
textController.text += key.text; textController.text += (key.text ?? '');
break; break;
case VirtualKeyboardKeyAction.Shift: case VirtualKeyboardKeyAction.Shift:
break; break;
@ -109,19 +109,18 @@ class _VirtualKeyboardState extends State<VirtualKeyboard> {
} }
} }
if(onKeyPress != null) onKeyPress?.call(key);
onKeyPress(key);
} }
@override dispose(){ @override
if(widget.textController == null) // dispose if created locally only dispose() {
textController?.dispose(); if (widget.textController == null) // dispose if created locally only
textController.dispose();
super.dispose(); super.dispose();
} }
@override @override
void didUpdateWidget(Widget oldWidget) { void didUpdateWidget(VirtualKeyboard oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
setState(() { setState(() {
type = widget.type; type = widget.type;
@ -131,9 +130,9 @@ class _VirtualKeyboardState extends State<VirtualKeyboard> {
textColor = widget.textColor; textColor = widget.textColor;
fontSize = widget.fontSize; fontSize = widget.fontSize;
alwaysCaps = widget.alwaysCaps; alwaysCaps = widget.alwaysCaps;
reverseLayout = widget.reverseLayout ?? false; reverseLayout = widget.reverseLayout;
textController = widget.textController ?? textController; textController = widget.textController ?? textController;
customLayoutKeys = widget.customLayoutKeys ?? customLayoutKeys ; customLayoutKeys = widget.customLayoutKeys ?? customLayoutKeys;
// Init the Text Style for keys. // Init the Text Style for keys.
textStyle = TextStyle( textStyle = TextStyle(
fontSize: fontSize, fontSize: fontSize,
@ -145,17 +144,19 @@ class _VirtualKeyboardState extends State<VirtualKeyboard> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
textController = widget.textController ?? TextEditingController(); textController = widget.textController ?? TextEditingController();
width = widget.width; width = widget.width;
type = widget.type; type = widget.type;
customLayoutKeys = widget.customLayoutKeys ?? VirtualKeyboardDefaultLayoutKeys(widget.defaultLayouts ?? [VirtualKeyboardDefaultLayouts.English]); customLayoutKeys = widget.customLayoutKeys ??
VirtualKeyboardDefaultLayoutKeys(
widget.defaultLayouts ?? [VirtualKeyboardDefaultLayouts.English]);
onKeyPress = widget.onKeyPress; onKeyPress = widget.onKeyPress;
height = widget.height; height = widget.height;
textColor = widget.textColor; textColor = widget.textColor;
fontSize = widget.fontSize; fontSize = widget.fontSize;
alwaysCaps = widget.alwaysCaps; alwaysCaps = widget.alwaysCaps;
reverseLayout = widget.reverseLayout ?? false; reverseLayout = widget.reverseLayout;
// Init the Text Style for keys. // Init the Text Style for keys.
textStyle = TextStyle( textStyle = TextStyle(
fontSize: fontSize, fontSize: fontSize,
@ -202,44 +203,40 @@ class _VirtualKeyboardState extends State<VirtualKeyboard> {
// Generate keyboard row. // Generate keyboard row.
List<Widget> rows = List.generate(keyboardRows.length, (int rowNum) { List<Widget> rows = List.generate(keyboardRows.length, (int rowNum) {
var items =List.generate( var items = List.generate(keyboardRows[rowNum].length, (int keyNum) {
keyboardRows[rowNum].length, // Get the VirtualKeyboardKey object.
(int keyNum) { VirtualKeyboardKey virtualKeyboardKey = keyboardRows[rowNum][keyNum];
// Get the VirtualKeyboardKey object.
VirtualKeyboardKey virtualKeyboardKey =
keyboardRows[rowNum][keyNum];
Widget keyWidget; Widget keyWidget;
// Check if builder is specified. // Check if builder is specified.
// Call builder function if specified or use default // Call builder function if specified or use default
// Key widgets if not. // Key widgets if not.
if (builder == null) { if (builder == null) {
// Check the key type. // Check the key type.
switch (virtualKeyboardKey.keyType) { switch (virtualKeyboardKey.keyType) {
case VirtualKeyboardKeyType.String: case VirtualKeyboardKeyType.String:
// Draw String key. // Draw String key.
keyWidget = _keyboardDefaultKey(virtualKeyboardKey); keyWidget = _keyboardDefaultKey(virtualKeyboardKey);
break; break;
case VirtualKeyboardKeyType.Action: case VirtualKeyboardKeyType.Action:
// Draw action key. // Draw action key.
keyWidget = _keyboardDefaultActionKey(virtualKeyboardKey); keyWidget = _keyboardDefaultActionKey(virtualKeyboardKey);
break; break;
} }
} else { } else {
// Call the builder function, so the user can specify custom UI for keys. // Call the builder function, so the user can specify custom UI for keys.
keyWidget = builder(context, virtualKeyboardKey); keyWidget = builder!(context, virtualKeyboardKey);
if (keyWidget == null) { // if (keyWidget == null) {
throw 'builder function must return Widget'; // throw 'builder function must return Widget';
} // }
} }
return keyWidget; return keyWidget;
}); });
if(this.reverseLayout) if (this.reverseLayout) items = items.reversed.toList();
items = items.reversed.toList();
return Material( return Material(
color: Colors.transparent, color: Colors.transparent,
child: Row( child: Row(
@ -255,7 +252,7 @@ class _VirtualKeyboardState extends State<VirtualKeyboard> {
} }
// True if long press is enabled. // True if long press is enabled.
bool longPress; bool longPress = false;
/// Creates default UI element for keyboard Key. /// Creates default UI element for keyboard Key.
Widget _keyboardDefaultKey(VirtualKeyboardKey key) { Widget _keyboardDefaultKey(VirtualKeyboardKey key) {
@ -269,8 +266,8 @@ class _VirtualKeyboardState extends State<VirtualKeyboard> {
child: Center( child: Center(
child: Text( child: Text(
alwaysCaps alwaysCaps
? key.capsText ? key.capsText ?? ''
: (isShiftEnabled ? key.capsText : key.text), : (isShiftEnabled ? key.capsText : key.text) ?? '',
style: textStyle, style: textStyle,
)), )),
), ),
@ -280,10 +277,10 @@ class _VirtualKeyboardState extends State<VirtualKeyboard> {
/// Creates default UI element for keyboard Action Key. /// Creates default UI element for keyboard Action Key.
Widget _keyboardDefaultActionKey(VirtualKeyboardKey key) { Widget _keyboardDefaultActionKey(VirtualKeyboardKey key) {
// Holds the action key widget. // Holds the action key widget.
Widget actionKey; Widget? actionKey;
// Switch the action type to build action Key widget. // Switch the action type to build action Key widget.
switch (key.action) { switch (key.action ?? VirtualKeyboardKeyAction.SwithLanguage) {
case VirtualKeyboardKeyAction.Backspace: case VirtualKeyboardKeyAction.Backspace:
actionKey = GestureDetector( actionKey = GestureDetector(
onLongPress: () { onLongPress: () {
@ -329,7 +326,7 @@ class _VirtualKeyboardState extends State<VirtualKeyboard> {
actionKey = GestureDetector( actionKey = GestureDetector(
onTap: () { onTap: () {
setState(() { setState(() {
customLayoutKeys.switchLanguage(); customLayoutKeys.switchLanguage();
}); });
}, },
child: Container( child: Container(
@ -341,32 +338,31 @@ class _VirtualKeyboardState extends State<VirtualKeyboard> {
), ),
)); ));
break; break;
break;
} }
var wdgt =InkWell( var wdgt = InkWell(
onTap: () { onTap: () {
if (key.action == VirtualKeyboardKeyAction.Shift) { if (key.action == VirtualKeyboardKeyAction.Shift) {
if (!alwaysCaps) { if (!alwaysCaps) {
setState(() { setState(() {
isShiftEnabled = !isShiftEnabled; isShiftEnabled = !isShiftEnabled;
}); });
}
} }
}
_onKeyPress(key); _onKeyPress(key);
}, },
child: Container( child: Container(
alignment: Alignment.center, alignment: Alignment.center,
height: height / customLayoutKeys.activeLayout.length, height: height / customLayoutKeys.activeLayout.length,
child: actionKey, child: actionKey,
), ),
); );
if(key.action == VirtualKeyboardKeyAction.Space) if (key.action == VirtualKeyboardKeyAction.Space)
return SizedBox(width: (width ?? MediaQuery.of(context).size.width)/2, child:wdgt); return SizedBox(
width: (width ?? MediaQuery.of(context).size.width) / 2, child: wdgt);
else else
return Expanded(child:wdgt); return Expanded(child: wdgt);
} }
} }

View File

@ -1,49 +1,43 @@
part of virtual_keyboard_multi_language; part of virtual_keyboard_multi_language;
//import '../virtual_keyboard_multi_language.dart'; //import '../virtual_keyboard_multi_language.dart';
abstract class VirtualKeyboardLayoutKeys{ abstract class VirtualKeyboardLayoutKeys {
int activeIndex = 0;
int activeIndex =0;
List<List> get defaultEnglishLayout => _defaultEnglishLayout; List<List> get defaultEnglishLayout => _defaultEnglishLayout;
List<List> get defaultArabicLayout => _defaultArabicLayout; List<List> get defaultArabicLayout => _defaultArabicLayout;
List<List> get activeLayout => getLanguage(activeIndex); List<List> get activeLayout => getLanguage(activeIndex);
int getLanguagesCount(); int getLanguagesCount();
List<List> getLanguage(int index); List<List> getLanguage(int index);
void switchLanguage(){ void switchLanguage() {
if((activeIndex+1) == getLanguagesCount()) if ((activeIndex + 1) == getLanguagesCount())
activeIndex =0; activeIndex = 0;
else activeIndex++; else
activeIndex++;
} }
} }
class VirtualKeyboardDefaultLayoutKeys extends VirtualKeyboardLayoutKeys{ class VirtualKeyboardDefaultLayoutKeys extends VirtualKeyboardLayoutKeys {
List<VirtualKeyboardDefaultLayouts> defaultLayouts; List<VirtualKeyboardDefaultLayouts> defaultLayouts;
VirtualKeyboardDefaultLayoutKeys(this.defaultLayouts); VirtualKeyboardDefaultLayoutKeys(this.defaultLayouts);
int getLanguagesCount() => defaultLayouts.length; int getLanguagesCount() => defaultLayouts.length;
List<List> getLanguage(int index){ List<List> getLanguage(int index) {
switch (defaultLayouts[index]) {
switch(defaultLayouts[index]){
case VirtualKeyboardDefaultLayouts.English: case VirtualKeyboardDefaultLayouts.English:
return _defaultEnglishLayout; return _defaultEnglishLayout;
case VirtualKeyboardDefaultLayouts.Arabic: case VirtualKeyboardDefaultLayouts.Arabic:
return _defaultArabicLayout; return _defaultArabicLayout;
default: default:
} }
return _defaultEnglishLayout; return _defaultEnglishLayout;
} }
} }
/// Keys for Virtual Keyboard's rows. /// Keys for Virtual Keyboard's rows.
const List<List> _defaultEnglishLayout = [ const List<List> _defaultEnglishLayout = [
// Row 1 // Row 1
const [ const [
@ -112,7 +106,6 @@ const List<List> _defaultEnglishLayout = [
] ]
]; ];
const List<List> _defaultArabicLayout = [ const List<List> _defaultArabicLayout = [
// Row 1 // Row 1
const [ const [
@ -139,6 +132,7 @@ const List<List> _defaultArabicLayout = [
'ه', 'ه',
'خ', 'خ',
'ح', 'ح',
'ج',
'د', 'د',
VirtualKeyboardKeyAction.Backspace VirtualKeyboardKeyAction.Backspace
], ],
@ -168,7 +162,7 @@ const List<List> _defaultArabicLayout = [
'ى', 'ى',
'ة', 'ة',
'و', 'و',
'.', 'ز',
'ظ', 'ظ',
VirtualKeyboardKeyAction.Shift VirtualKeyboardKeyAction.Shift
], ],
@ -178,6 +172,7 @@ const List<List> _defaultArabicLayout = [
'@', '@',
VirtualKeyboardKeyAction.Space, VirtualKeyboardKeyAction.Space,
'-', '-',
'.',
'_', '_',
] ]
]; ];

View File

@ -1,11 +1,11 @@
name: virtual_keyboard_multi_language name: virtual_keyboard_multi_language
description: A simple package for dispaying virtual keyboards on a devices like kiosks and ATMs. The library is written in Dart and has no native code dependancy. description: A simple package for dispaying virtual keyboards on a devices like kiosks and ATMs. The library is written in Dart and has no native code dependancy.
version: 0.2.2 version: 1.0.1
#author: Ahmed El-Araby <ahmed-eg@live.com> #author: Ahmed El-Araby <ahmed-eg@live.com>
homepage: https://github.com/ahmed-eg/virtual_keyboard_multi_language homepage: https://github.com/ahmed-eg/virtual_keyboard_multi_language
environment: environment:
sdk: ">=2.1.0 <3.0.0" sdk: ">=2.12.0 <3.0.0"
dependencies: dependencies:
flutter: flutter: