Skip to content

Instantly share code, notes, and snippets.

@roipeker
Created April 15, 2020 23:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save roipeker/0828f32a66ad931031913cf3b36b4e68 to your computer and use it in GitHub Desktop.
Save roipeker/0828f32a66ad931031913cf3b36b4e68 to your computer and use it in GitHub Desktop.
Flutter Keyboard emulation, caret position and selection, para Manu.
import 'dart:ui';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Manu Keyboard'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
buildInput(),
_row([
_btn("1", () => "1"),
_btn("2", () => "2"),
_btn("3", () => "3"),
]),
_row([
_btn("4", () => "4"),
_btn("5", () => "5"),
_btn("6", () => "6"),
]),
_row([
_btn("7", () => "7"),
_btn("8", () => "8"),
_btn("9", () => "9"),
]),
_row([
_btn(".", () => ","),
_btn("0", () => "0"),
_btn("C", () => "C"),
]),
],
),
),
);
}
_row(List<Widget> children) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: children,
),
);
}
Widget _btn(String label, Function callback) {
return MaterialButton(
padding: EdgeInsets.all(16),
child: Text(
label,
style: TextStyle(color: Colors.white),
),
shape: CircleBorder(),
color: Colors.blue,
highlightColor: Colors.black12,
onPressed: () {
var res = callback();
if (res == 'C') {
_clearText();
} else {
_addChar(res);
}
},
);
}
void _clearText() {
_textController.clear();
}
TextEditingController _textController;
FocusNode _focusNode;
TextSelection _lastSelection;
@override
void initState() {
_textController = TextEditingController();
_focusNode = FocusNode();
_focusNode.addListener(() {
if (!_focusNode.hasFocus && _focusNode.canRequestFocus) {
_focusNode.requestFocus();
_lastSelection = _textController.selection;
} else {
if (_lastSelection != null) {
_textController.selection = _lastSelection;
}
}
});
super.initState();
}
Widget buildInput() {
return SizedBox(
width: 300,
child: TextField(
controller: _textController,
focusNode: _focusNode,
decoration: InputDecoration(
border: OutlineInputBorder(),
),
),
);
}
void _addChar(String char) {
if (!_focusNode.hasFocus) {
_focusNode.requestFocus();
}
if (_lastSelection == null) {
_lastSelection = _textController.selection;
print('asd $_lastSelection');
}
var txt = _textController.text;
var base = _lastSelection.baseOffset;
var part1 = base == -1 ? '' : txt.substring(0, _lastSelection.baseOffset);
var part2 = _lastSelection.extentOffset == -1
? ''
: txt.substring(_lastSelection.extentOffset);
// evitar problema de cursor cuando no tiene foco el textfield.
if (base == -1) base = 0;
var caretPos = base + char.length;
// _lastSelection.extentOffset == _lastSelection.baseOffset ? CURSOR : SELECCION
_textController.text = part1 + char + part2;
_lastSelection =
_lastSelection.copyWith(extentOffset: caretPos, baseOffset: caretPos);
_textController.selection = _lastSelection;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment