null safety support
This commit is contained in:
parent
143bedc6ac
commit
1d363db57d
1
.gitignore
vendored
1
.gitignore
vendored
@ -18,6 +18,7 @@
|
||||
|
||||
# Visual Studio Code related
|
||||
.vscode/
|
||||
.vs/
|
||||
|
||||
# Flutter/Dart/Pub related
|
||||
**/doc/api/
|
||||
|
10
CHANGELOG.md
10
CHANGELOG.md
@ -21,4 +21,12 @@
|
||||
## [0.2.2] - 19/03/2020.
|
||||
|
||||
* 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
|
@ -1,10 +1,13 @@
|
||||
#!/bin/sh
|
||||
# This is a generated file; do not edit or check into version control.
|
||||
export "FLUTTER_ROOT=C:\src\flutter"
|
||||
export "FLUTTER_APPLICATION_PATH=D:\_Workspace\virtual_keyboard_multi_language\example"
|
||||
export "FLUTTER_ROOT=C:\Flutter\flutter"
|
||||
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_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_NUMBER=1"
|
||||
export "DART_OBFUSCATION=false"
|
||||
export "TRACK_WIDGET_CREATION=false"
|
||||
export "TREE_SHAKE_ICONS=false"
|
||||
export "PACKAGE_CONFIG=.dart_tool/package_config.json"
|
||||
|
@ -1,6 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:virtual_keyboard_multi_language/virtual_keyboard_multi_language.dart';
|
||||
import 'package:example/custom_layout.dart';
|
||||
|
||||
void main() => runApp(MyApp());
|
||||
|
||||
@ -28,7 +27,7 @@ class MyHomePage extends StatefulWidget {
|
||||
class _MyHomePageState extends State<MyHomePage> {
|
||||
// Holds the text that user typed.
|
||||
String text = '';
|
||||
CustomLayoutKeys _customLayoutKeys;
|
||||
// CustomLayoutKeys _customLayoutKeys;
|
||||
// True if shift enabled.
|
||||
bool shiftEnabled = false;
|
||||
|
||||
@ -39,7 +38,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_customLayoutKeys = CustomLayoutKeys();
|
||||
// _customLayoutKeys = CustomLayoutKeys();
|
||||
_controllerText = TextEditingController();
|
||||
super.initState();
|
||||
}
|
||||
@ -55,7 +54,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
children: <Widget>[
|
||||
Text(
|
||||
text,
|
||||
style: Theme.of(context).textTheme.display1,
|
||||
style: Theme.of(context).textTheme.bodyText1,
|
||||
),
|
||||
Text(
|
||||
_controllerText.text,
|
||||
@ -85,8 +84,11 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
//width: 500,
|
||||
textColor: Colors.white,
|
||||
textController: _controllerText,
|
||||
//customLayoutKeys: _customLayoutKeys,
|
||||
defaultLayouts: [VirtualKeyboardDefaultLayouts.Arabic,VirtualKeyboardDefaultLayouts.English],
|
||||
//customLayoutKeys: _customLayoutKeys,
|
||||
defaultLayouts: [
|
||||
VirtualKeyboardDefaultLayouts.Arabic,
|
||||
VirtualKeyboardDefaultLayouts.English
|
||||
],
|
||||
//reverseLayout :true,
|
||||
type: isNumericMode
|
||||
? VirtualKeyboardType.Numeric
|
||||
|
@ -2,19 +2,22 @@ part of virtual_keyboard_multi_language;
|
||||
|
||||
/// Virtual Keyboard key
|
||||
class VirtualKeyboardKey {
|
||||
String text;
|
||||
String capsText;
|
||||
String? text;
|
||||
String? capsText;
|
||||
final VirtualKeyboardKeyType keyType;
|
||||
final VirtualKeyboardKeyAction action;
|
||||
final VirtualKeyboardKeyAction? action;
|
||||
|
||||
VirtualKeyboardKey(
|
||||
{this.text, this.capsText, @required this.keyType, this.action}){
|
||||
|
||||
if(this.text == null && this.action != null){
|
||||
this.text = action == VirtualKeyboardKeyAction.Space ? ' ' : (action == VirtualKeyboardKeyAction.Return ? '\n' : '');
|
||||
}
|
||||
if(this.capsText == null && this.action != null){
|
||||
this.capsText = action == VirtualKeyboardKeyAction.Space ? ' ' : (action == VirtualKeyboardKeyAction.Return ? '\n' : '');
|
||||
}
|
||||
}
|
||||
{this.text, this.capsText, required this.keyType, this.action}) {
|
||||
if (this.text == null && this.action != null) {
|
||||
this.text = action == VirtualKeyboardKeyAction.Space
|
||||
? ' '
|
||||
: (action == VirtualKeyboardKeyAction.Return ? '\n' : '');
|
||||
}
|
||||
if (this.capsText == null && this.action != null) {
|
||||
this.capsText = action == VirtualKeyboardKeyAction.Space
|
||||
? ' '
|
||||
: (action == VirtualKeyboardKeyAction.Return ? '\n' : '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,28 +12,28 @@ class VirtualKeyboard extends StatefulWidget {
|
||||
final VirtualKeyboardType type;
|
||||
|
||||
/// Callback for Key press event. Called with pressed `Key` object.
|
||||
final Function onKeyPress;
|
||||
final Function? onKeyPress;
|
||||
|
||||
/// Virtual keyboard height. Default is 300
|
||||
final double height;
|
||||
|
||||
/// Virtual keyboard height. Default is full screen width
|
||||
final double width;
|
||||
final double? width;
|
||||
|
||||
/// Color for key texts and icons.
|
||||
final Color textColor;
|
||||
|
||||
/// Font size for keyboard keys.
|
||||
final double fontSize;
|
||||
|
||||
|
||||
/// 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
|
||||
final TextEditingController textController;
|
||||
final TextEditingController? textController;
|
||||
|
||||
/// 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.
|
||||
final bool alwaysCaps;
|
||||
@ -43,11 +43,11 @@ class VirtualKeyboard extends StatefulWidget {
|
||||
|
||||
/// used for multi-languages with default layouts, the default is English only
|
||||
/// will be ignored if customLayoutKeys is not null
|
||||
final List<VirtualKeyboardDefaultLayouts> defaultLayouts;
|
||||
final List<VirtualKeyboardDefaultLayouts>? defaultLayouts;
|
||||
|
||||
VirtualKeyboard(
|
||||
{Key key,
|
||||
@required this.type,
|
||||
{Key? key,
|
||||
required this.type,
|
||||
this.onKeyPress,
|
||||
this.builder,
|
||||
this.width,
|
||||
@ -69,39 +69,39 @@ class VirtualKeyboard extends StatefulWidget {
|
||||
|
||||
/// Holds the state for Virtual Keyboard class.
|
||||
class _VirtualKeyboardState extends State<VirtualKeyboard> {
|
||||
VirtualKeyboardType type;
|
||||
Function onKeyPress;
|
||||
TextEditingController textController;
|
||||
late VirtualKeyboardType type;
|
||||
Function? onKeyPress;
|
||||
late TextEditingController textController;
|
||||
// The builder function will be called for each Key object.
|
||||
Widget Function(BuildContext context, VirtualKeyboardKey key) builder;
|
||||
double height;
|
||||
double width;
|
||||
Color textColor;
|
||||
double fontSize;
|
||||
bool alwaysCaps;
|
||||
bool reverseLayout;
|
||||
VirtualKeyboardLayoutKeys customLayoutKeys;
|
||||
Widget Function(BuildContext context, VirtualKeyboardKey key)? builder;
|
||||
late double height;
|
||||
double? width;
|
||||
late Color textColor;
|
||||
late double fontSize;
|
||||
late bool alwaysCaps;
|
||||
late bool reverseLayout;
|
||||
late VirtualKeyboardLayoutKeys customLayoutKeys;
|
||||
// Text Style for keys.
|
||||
TextStyle textStyle;
|
||||
late TextStyle textStyle;
|
||||
|
||||
// True if shift is enabled.
|
||||
bool isShiftEnabled = false;
|
||||
|
||||
void _onKeyPress(VirtualKeyboardKey key){
|
||||
|
||||
void _onKeyPress(VirtualKeyboardKey key) {
|
||||
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) {
|
||||
switch (key.action) {
|
||||
case VirtualKeyboardKeyAction.Backspace:
|
||||
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;
|
||||
case VirtualKeyboardKeyAction.Return:
|
||||
textController.text += '\n';
|
||||
break;
|
||||
case VirtualKeyboardKeyAction.Space:
|
||||
textController.text += key.text;
|
||||
textController.text += (key.text ?? '');
|
||||
break;
|
||||
case VirtualKeyboardKeyAction.Shift:
|
||||
break;
|
||||
@ -109,19 +109,18 @@ class _VirtualKeyboardState extends State<VirtualKeyboard> {
|
||||
}
|
||||
}
|
||||
|
||||
if(onKeyPress != null)
|
||||
onKeyPress(key);
|
||||
|
||||
onKeyPress?.call(key);
|
||||
}
|
||||
|
||||
@override dispose(){
|
||||
if(widget.textController == null) // dispose if created locally only
|
||||
textController?.dispose();
|
||||
@override
|
||||
dispose() {
|
||||
if (widget.textController == null) // dispose if created locally only
|
||||
textController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(Widget oldWidget) {
|
||||
void didUpdateWidget(VirtualKeyboard oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
setState(() {
|
||||
type = widget.type;
|
||||
@ -131,9 +130,9 @@ class _VirtualKeyboardState extends State<VirtualKeyboard> {
|
||||
textColor = widget.textColor;
|
||||
fontSize = widget.fontSize;
|
||||
alwaysCaps = widget.alwaysCaps;
|
||||
reverseLayout = widget.reverseLayout ?? false;
|
||||
reverseLayout = widget.reverseLayout;
|
||||
textController = widget.textController ?? textController;
|
||||
customLayoutKeys = widget.customLayoutKeys ?? customLayoutKeys ;
|
||||
customLayoutKeys = widget.customLayoutKeys ?? customLayoutKeys;
|
||||
// Init the Text Style for keys.
|
||||
textStyle = TextStyle(
|
||||
fontSize: fontSize,
|
||||
@ -145,17 +144,19 @@ class _VirtualKeyboardState extends State<VirtualKeyboard> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
|
||||
textController = widget.textController ?? TextEditingController();
|
||||
width = widget.width;
|
||||
type = widget.type;
|
||||
customLayoutKeys = widget.customLayoutKeys ?? VirtualKeyboardDefaultLayoutKeys(widget.defaultLayouts ?? [VirtualKeyboardDefaultLayouts.English]);
|
||||
customLayoutKeys = widget.customLayoutKeys ??
|
||||
VirtualKeyboardDefaultLayoutKeys(
|
||||
widget.defaultLayouts ?? [VirtualKeyboardDefaultLayouts.English]);
|
||||
onKeyPress = widget.onKeyPress;
|
||||
height = widget.height;
|
||||
textColor = widget.textColor;
|
||||
fontSize = widget.fontSize;
|
||||
alwaysCaps = widget.alwaysCaps;
|
||||
reverseLayout = widget.reverseLayout ?? false;
|
||||
reverseLayout = widget.reverseLayout;
|
||||
// Init the Text Style for keys.
|
||||
textStyle = TextStyle(
|
||||
fontSize: fontSize,
|
||||
@ -202,44 +203,40 @@ class _VirtualKeyboardState extends State<VirtualKeyboard> {
|
||||
|
||||
// Generate keyboard row.
|
||||
List<Widget> rows = List.generate(keyboardRows.length, (int rowNum) {
|
||||
var items =List.generate(
|
||||
keyboardRows[rowNum].length,
|
||||
(int keyNum) {
|
||||
// Get the VirtualKeyboardKey object.
|
||||
VirtualKeyboardKey virtualKeyboardKey =
|
||||
keyboardRows[rowNum][keyNum];
|
||||
var items = List.generate(keyboardRows[rowNum].length, (int keyNum) {
|
||||
// Get the VirtualKeyboardKey object.
|
||||
VirtualKeyboardKey virtualKeyboardKey = keyboardRows[rowNum][keyNum];
|
||||
|
||||
Widget keyWidget;
|
||||
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);
|
||||
// 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';
|
||||
}
|
||||
}
|
||||
// if (keyWidget == null) {
|
||||
// throw 'builder function must return Widget';
|
||||
// }
|
||||
}
|
||||
|
||||
return keyWidget;
|
||||
});
|
||||
return keyWidget;
|
||||
});
|
||||
|
||||
if(this.reverseLayout)
|
||||
items = items.reversed.toList();
|
||||
if (this.reverseLayout) items = items.reversed.toList();
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
child: Row(
|
||||
@ -255,7 +252,7 @@ class _VirtualKeyboardState extends State<VirtualKeyboard> {
|
||||
}
|
||||
|
||||
// True if long press is enabled.
|
||||
bool longPress;
|
||||
bool longPress = false;
|
||||
|
||||
/// Creates default UI element for keyboard Key.
|
||||
Widget _keyboardDefaultKey(VirtualKeyboardKey key) {
|
||||
@ -269,8 +266,8 @@ class _VirtualKeyboardState extends State<VirtualKeyboard> {
|
||||
child: Center(
|
||||
child: Text(
|
||||
alwaysCaps
|
||||
? key.capsText
|
||||
: (isShiftEnabled ? key.capsText : key.text),
|
||||
? key.capsText ?? ''
|
||||
: (isShiftEnabled ? key.capsText : key.text) ?? '',
|
||||
style: textStyle,
|
||||
)),
|
||||
),
|
||||
@ -280,10 +277,10 @@ class _VirtualKeyboardState extends State<VirtualKeyboard> {
|
||||
/// Creates default UI element for keyboard Action Key.
|
||||
Widget _keyboardDefaultActionKey(VirtualKeyboardKey key) {
|
||||
// Holds the action key widget.
|
||||
Widget actionKey;
|
||||
Widget? actionKey;
|
||||
|
||||
// Switch the action type to build action Key widget.
|
||||
switch (key.action) {
|
||||
switch (key.action ?? VirtualKeyboardKeyAction.SwithLanguage) {
|
||||
case VirtualKeyboardKeyAction.Backspace:
|
||||
actionKey = GestureDetector(
|
||||
onLongPress: () {
|
||||
@ -329,7 +326,7 @@ class _VirtualKeyboardState extends State<VirtualKeyboard> {
|
||||
actionKey = GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
customLayoutKeys.switchLanguage();
|
||||
customLayoutKeys.switchLanguage();
|
||||
});
|
||||
},
|
||||
child: Container(
|
||||
@ -341,32 +338,31 @@ class _VirtualKeyboardState extends State<VirtualKeyboard> {
|
||||
),
|
||||
));
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
var wdgt =InkWell(
|
||||
onTap: () {
|
||||
if (key.action == VirtualKeyboardKeyAction.Shift) {
|
||||
if (!alwaysCaps) {
|
||||
setState(() {
|
||||
isShiftEnabled = !isShiftEnabled;
|
||||
});
|
||||
}
|
||||
var wdgt = InkWell(
|
||||
onTap: () {
|
||||
if (key.action == VirtualKeyboardKeyAction.Shift) {
|
||||
if (!alwaysCaps) {
|
||||
setState(() {
|
||||
isShiftEnabled = !isShiftEnabled;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_onKeyPress(key);
|
||||
},
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
height: height / customLayoutKeys.activeLayout.length,
|
||||
child: actionKey,
|
||||
),
|
||||
);
|
||||
_onKeyPress(key);
|
||||
},
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
height: height / customLayoutKeys.activeLayout.length,
|
||||
child: actionKey,
|
||||
),
|
||||
);
|
||||
|
||||
if(key.action == VirtualKeyboardKeyAction.Space)
|
||||
return SizedBox(width: (width ?? MediaQuery.of(context).size.width)/2, child:wdgt);
|
||||
if (key.action == VirtualKeyboardKeyAction.Space)
|
||||
return SizedBox(
|
||||
width: (width ?? MediaQuery.of(context).size.width) / 2, child: wdgt);
|
||||
else
|
||||
return Expanded(child:wdgt);
|
||||
|
||||
return Expanded(child: wdgt);
|
||||
}
|
||||
}
|
||||
|
@ -1,49 +1,43 @@
|
||||
part of virtual_keyboard_multi_language;
|
||||
//import '../virtual_keyboard_multi_language.dart';
|
||||
|
||||
abstract class VirtualKeyboardLayoutKeys{
|
||||
|
||||
int activeIndex =0;
|
||||
abstract class VirtualKeyboardLayoutKeys {
|
||||
int activeIndex = 0;
|
||||
|
||||
List<List> get defaultEnglishLayout => _defaultEnglishLayout;
|
||||
List<List> get defaultArabicLayout => _defaultArabicLayout;
|
||||
|
||||
List<List> get activeLayout => getLanguage(activeIndex);
|
||||
List<List> get activeLayout => getLanguage(activeIndex);
|
||||
int getLanguagesCount();
|
||||
List<List> getLanguage(int index);
|
||||
|
||||
void switchLanguage(){
|
||||
if((activeIndex+1) == getLanguagesCount())
|
||||
activeIndex =0;
|
||||
else activeIndex++;
|
||||
void switchLanguage() {
|
||||
if ((activeIndex + 1) == getLanguagesCount())
|
||||
activeIndex = 0;
|
||||
else
|
||||
activeIndex++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class VirtualKeyboardDefaultLayoutKeys extends VirtualKeyboardLayoutKeys{
|
||||
|
||||
class VirtualKeyboardDefaultLayoutKeys extends VirtualKeyboardLayoutKeys {
|
||||
List<VirtualKeyboardDefaultLayouts> defaultLayouts;
|
||||
VirtualKeyboardDefaultLayoutKeys(this.defaultLayouts);
|
||||
|
||||
int getLanguagesCount() => defaultLayouts.length;
|
||||
|
||||
List<List> getLanguage(int index){
|
||||
|
||||
switch(defaultLayouts[index]){
|
||||
List<List> getLanguage(int index) {
|
||||
switch (defaultLayouts[index]) {
|
||||
case VirtualKeyboardDefaultLayouts.English:
|
||||
return _defaultEnglishLayout;
|
||||
return _defaultEnglishLayout;
|
||||
case VirtualKeyboardDefaultLayouts.Arabic:
|
||||
return _defaultArabicLayout;
|
||||
return _defaultArabicLayout;
|
||||
default:
|
||||
}
|
||||
return _defaultEnglishLayout;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// Keys for Virtual Keyboard's rows.
|
||||
/// Keys for Virtual Keyboard's rows.
|
||||
const List<List> _defaultEnglishLayout = [
|
||||
// Row 1
|
||||
const [
|
||||
@ -112,7 +106,6 @@ const List<List> _defaultEnglishLayout = [
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
const List<List> _defaultArabicLayout = [
|
||||
// Row 1
|
||||
const [
|
||||
@ -139,6 +132,7 @@ const List<List> _defaultArabicLayout = [
|
||||
'ه',
|
||||
'خ',
|
||||
'ح',
|
||||
'ج',
|
||||
'د',
|
||||
VirtualKeyboardKeyAction.Backspace
|
||||
],
|
||||
@ -168,7 +162,7 @@ const List<List> _defaultArabicLayout = [
|
||||
'ى',
|
||||
'ة',
|
||||
'و',
|
||||
'.',
|
||||
'ز',
|
||||
'ظ',
|
||||
VirtualKeyboardKeyAction.Shift
|
||||
],
|
||||
@ -178,6 +172,7 @@ const List<List> _defaultArabicLayout = [
|
||||
'@',
|
||||
VirtualKeyboardKeyAction.Space,
|
||||
'-',
|
||||
'.',
|
||||
'_',
|
||||
]
|
||||
];
|
||||
];
|
||||
|
@ -1,11 +1,11 @@
|
||||
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.
|
||||
version: 0.2.2
|
||||
version: 1.0.1
|
||||
#author: Ahmed El-Araby <ahmed-eg@live.com>
|
||||
homepage: https://github.com/ahmed-eg/virtual_keyboard_multi_language
|
||||
|
||||
environment:
|
||||
sdk: ">=2.1.0 <3.0.0"
|
||||
sdk: ">=2.12.0 <3.0.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
|
Loading…
x
Reference in New Issue
Block a user