flutter: How to detect keyboard? - flutter

I want detect Keyboard. And want to show it other text when keyboard is visible or unvisible.
But my code is not working.
This is my code.
class Search extends StatefulWidget {
#override
_SearchState createState() => _SearchState();
}
class _SearchState extends State<Search> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: Colors.white,
child: Column(
children: [
Expanded(
flex: 1,
child: ListView(
children: [
MediaQuery.of(context).viewInsets.bottom !=0 ? Center(child: Text("true"),) : Center(child: Text("false"),)
],
),
)
],
),
),
);
}
}

As #Anas Mohammed mentioned, you can do it with the keyboard_visibility package. Here is a total example:
import 'package:flutter/material.dart';
import 'package:keyboard_visibility/keyboard_visibility.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Keyboard visibility example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: KeyboardVisibilityExample(),
);
}
}
class KeyboardVisibilityExample extends StatefulWidget {
KeyboardVisibilityExample({Key key}) : super(key: key);
#override
_KeyboardVisibilityExampleState createState() => _KeyboardVisibilityExampleState();
}
class _KeyboardVisibilityExampleState extends State<KeyboardVisibilityExample> {
KeyboardVisibilityNotification _keyboardVisibility = new KeyboardVisibilityNotification();
int _keyboardVisibilitySubscriberId;
bool _keyboardState;
#protected
void initState() {
super.initState();
_keyboardState = _keyboardVisibility.isKeyboardVisible;
_keyboardVisibilitySubscriberId = _keyboardVisibility.addNewListener(
onChange: (bool visible) {
setState(() {
_keyboardState = visible;
});
},
);
}
#override
void dispose() {
_keyboardVisibility.removeListener(_keyboardVisibilitySubscriberId);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Keyboard visibility example'),
),
body: Center(
child: Padding(
padding: EdgeInsets.all(24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: 'Input box for keyboard test',
),
),
Container(height: 60.0),
Text(
'The current state of the keyboard is: ' + (_keyboardState ? 'VISIBLE' : 'NOT VISIBLE'),
),
],
)
),
),
);
}
}

for to visible keyboard this code:
FocusScope.of(context).requestFocus();
for to unvisible keyboard this code:
FocusScope.of(context).unfocus();
for check visiblity of keyboard :
FocusScope.of(context).hasFocus
your provided code:
class Search extends StatefulWidget {
#override
_SearchState createState() => _SearchState();
}
class _SearchState extends State<Search> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: Colors.white,
child: Column(
children: [
Expanded(
flex: 1,
child: ListView(
children: [
FocusScope.of(context).hasFocus ? Center(child: Text("true"),) : Center(child: Text("false"),)
],
),
)
],
),
),
);
}
}

Accepted answer contains old library not support null safety, you can use this one flutter_keyboard_visibility which support null safety.

Related

flutter Change part of text selected color in textfield

I want when the user selects a part of the text in textfield and clicks on the color button, only that part of the selected text will be colored.
Thanks
I searched all the articles but couldn't find any results.
Nima jan Salaam,
you need to use rich_text_controller package like this code below:
first of all add rich_text_controller: ^1.4.0 in your pubspec.yaml (or any compatible versions).
import 'package:flutter/material.dart';
import 'package:rich_text_controller/rich_text_controller.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: RichTextControllerDemo(),
);
}
}
class RichTextControllerDemo extends StatefulWidget {
const RichTextControllerDemo({super.key});
#override
State<RichTextControllerDemo> createState() => _RichTextControllerDemoState();
}
class _RichTextControllerDemoState extends State<RichTextControllerDemo> {
RichTextController? _controller;
#override
void initState() {
_controller = RichTextController(
stringMatchMap: {
"test": const TextStyle(color: Colors.red),
},
onMatch: (List<String> matches){
}
);
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
controller: _controller,
onChanged: (value){
},
),
Padding(
padding: const EdgeInsets.only(top : 20.0),
child: InkWell(
child: const Text('click'),
onTap: (){
var start = _controller!.selection.start;
var end = _controller!.selection.end;
var text = _controller!.text.substring(start,end);
setState(() {
_controller!.stringMatchMap!.addAll(
{
text : const TextStyle(color: Colors.cyan),
}
);
});
},
),
)
],
)),
);
}
}
happy coding bro...

why setState not working for List of widgets in flutter

I am new in flutter I try to experiment with List of Widget . I try to change state inside the list of widget i.e. initialized in initState . I create sample example to what I want to achieve.
class Testing extends StatefulWidget {
const Testing({super.key});
#override
State<Testing> createState() => _TestingState();
}
class _TestingState extends State<Testing> {
bool isChanged = false;
List<Widget> simpleWidget = [];
#override
void initState() {
simpleWidget = [_someComplexWidget(), _someComplexWidget()];
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title:const Text("Test"),
),
body: Center(
child: Column(
children: [
Container(
child: Column(
children: simpleWidget,
),
),
ElevatedButton(
onPressed: () {
setState(() {
isChanged = !isChanged;
});
},
child: const Text("Click"))
],
),
),
);
}
Widget _someComplexWidget() {
return Text(
"Hello",
style: TextStyle(color: isChanged ? Colors.red : Colors.blue),
);
}
}
I also try with keys but it did not work in this sample code. When to Use Keys
What is the reason behind not working this code.
Because your simpleWidget is created at initState & it will not change on rebuild.
You should add [_someComplexWidget(), _someComplexWidget()] under build for it to change dynamically based on the current state.
class Testing extends StatefulWidget {
const Testing({super.key});
#override
State<Testing> createState() => _TestingState();
}
class _TestingState extends State<Testing> {
bool isChanged = false;
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Test"),
),
body: Center(
child: Column(
children: [
Container(
child: Column(
children: [_someComplexWidget(), _someComplexWidget()], // HERE
),
),
ElevatedButton(
onPressed: () {
setState(() {
isChanged = !isChanged;
});
print(isChanged);
},
child: const Text("Click"))
],
),
),
);
}
Widget _someComplexWidget() {
return Text(
"Hello",
style: TextStyle(color: isChanged ? Colors.red : Colors.blue),
);
}
}

How to go back to previous screen by clicking on bottom navigation bar item in Flutter

I am using this library persistent_bottom_nav_bar to display bottom navigation bar even on navigating to new screen. Now there are two main pages Page1 and Page2, Page1 is using an icon of home where as Page2 is using an icon of search. In Page1 contain a button which navigate to new screen named as NewPage. What i wanted to achieve is if i navigate to NewPage from Page1 and if i decide to goback to previous screen which is Page1 by clicking on homeicon which is at bottom. So how can i click on bottom item and go back to previous screen? Hope you understand my question
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Demo',
home: HomeScaffold(),
);
}
}
class HomeScaffold extends StatefulWidget {
#override
_HomeScaffoldState createState() => _HomeScaffoldState();
}
class _HomeScaffoldState extends State<HomeScaffold> {
late PersistentTabController _controller;
#override
void initState() {
super.initState();
_controller = PersistentTabController(initialIndex: 0);
}
List<Widget> _buildScreens() {
return [
Page1(),
Page2(),
];
}
List<PersistentBottomNavBarItem> _navBarsItems() {
return [
_buildBottomNavBarItem('Page 1', Icons.home),
_buildBottomNavBarItem('Page 2', Icons.search),
];
}
#override
Widget build(BuildContext context) {
return PersistentTabView.custom(
context,
controller: _controller,
screens: _buildScreens(),
confineInSafeArea: true,
itemCount: 2,
handleAndroidBackButtonPress: true,
stateManagement: true,
screenTransitionAnimation: ScreenTransitionAnimation(
animateTabTransition: true,
curve: Curves.ease,
duration: Duration(milliseconds: 200),
),
customWidget: CustomNavBarWidget(
items: _navBarsItems(),
onItemSelected: (index) {
setState(() {
_controller.index = index; // go back to previous screen if i navigate to new screen
});
},
selectedIndex: _controller.index,
),
// ),
);
}
}
class CustomNavBarWidget extends StatelessWidget {
final int? selectedIndex;
final List<PersistentBottomNavBarItem> items;
final ValueChanged<int>? onItemSelected;
CustomNavBarWidget({
Key? key,
this.selectedIndex,
required this.items,
this.onItemSelected,
});
Widget _buildItem(PersistentBottomNavBarItem item, bool isSelected) {
return Container(
alignment: Alignment.center,
height: kBottomNavigationBarHeight,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Flexible(
child: IconTheme(
data: IconThemeData(
size: 26.0,
color: isSelected
? (item.activeColorSecondary == null
? item.activeColorPrimary
: item.activeColorSecondary)
: item.inactiveColorPrimary == null
? item.activeColorPrimary
: item.inactiveColorPrimary),
child: isSelected ? item.icon : item.inactiveIcon ?? item.icon,
),
),
Padding(
padding: const EdgeInsets.only(top: 5.0),
child: Material(
type: MaterialType.transparency,
child: FittedBox(
child: Text(
item.title!,
style: TextStyle(
color: isSelected
? (item.activeColorSecondary == null
? item.activeColorPrimary
: item.activeColorSecondary)
: item.inactiveColorPrimary,
fontWeight: FontWeight.w400,
fontSize: 12.0),
)),
),
)
],
),
);
}
#override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: Container(
width: double.infinity,
height: kBottomNavigationBarHeight,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: items.map((item) {
int index = items.indexOf(item);
return Flexible(
child: GestureDetector(
onTap: () {
this.onItemSelected!(index);
},
child: _buildItem(item, selectedIndex == index),
),
);
}).toList(),
),
),
);
}
}
PersistentBottomNavBarItem _buildBottomNavBarItem(String title, IconData icon) {
return PersistentBottomNavBarItem(
icon: Icon(icon),
title: title,
activeColorPrimary: Colors.indigo,
inactiveColorPrimary: Colors.grey,
);
}
class Page1 extends StatefulWidget {
const Page1({Key? key}) : super(key: key);
#override
_Page1State createState() => _Page1State();
}
class _Page1State extends State<Page1> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Container(
child: Center(
child: TextButton(
onPressed: () {
Navigator.push(
context, CupertinoPageRoute(builder: (context) => NewPage()));
},
child: Text('Click'),
),
),
),
);
}
}
class Page2 extends StatefulWidget {
const Page2({Key? key}) : super(key: key);
#override
_Page2State createState() => _Page2State();
}
class _Page2State extends State<Page2> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.red,
body: Container(),
);
}
}
class NewPage extends StatefulWidget {
const NewPage({Key? key}) : super(key: key);
#override
_NewPageState createState() => _NewPageState();
}
class _NewPageState extends State<NewPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(),
);
}
}
Have you tried simply using the built-in Navigator.of(context).pop() function as the onPressed callback?

Flutter TextField value disappear when clicked on another textField

Am New in Flutter, Now am trying to add ModalBottomSheet with some textfields and whenever i try to tap on another textField then value got disappeared automatically.
Here is my new_user.dart file
import 'package:flutter/material.dart';
class newUsers extends StatelessWidget {
var nameInputController = TextEditingController();
var marksInputController = TextEditingController();
Function? addNewUser;
newUsers(this.addNewUser);
void submitData() {
print(nameInputController.text);
if (nameInputController.text.isEmpty || marksInputController.text.isEmpty) {
return;
}
addNewUser!(
nameInputController.text, double.parse(marksInputController.text));
}
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
TextField(
decoration: InputDecoration(labelText: "Name"),
controller: nameInputController,
),
TextField(
decoration: InputDecoration(labelText: "Marks"),
controller: marksInputController,
keyboardType: TextInputType.number,
),
ElevatedButton(
onPressed: submitData,
child: Text('Add User Details'),
),
],
),
);
}
}
Home.dart
import 'package:expense_manager/widgets/new_users.dart';
import 'package:expense_manager/widgets/users.dart';
import 'package:expense_manager/widgets/users_list.dart';
import 'models/users.dart';
import 'package:flutter/material.dart';
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
List<User> users = [
User(id: 1, name: 'himanshurahi', marks: 44.5, createdAt: DateTime.now()),
];
void addNewUser(String name, double marks) {
var newUser =
User(id: 1, name: name, marks: marks, createdAt: DateTime.now());
setState(() {
users.add(newUser);
});
}
#override
Widget build(BuildContext context) {
void addNewUserWithSheet(BuildContext context) {
showModalBottomSheet(
context: context,
builder: (btx) {
return newUsers(addNewUser);
},
);
}
return Scaffold(
appBar: AppBar(
title: Text('my App'),
actions: [
IconButton(
onPressed: () => addNewUserWithSheet(context),
icon: Icon(Icons.add))
],
),
floatingActionButton: FloatingActionButton(
onPressed: () => addNewUserWithSheet(context),
child: Icon(Icons.add)),
body: Container(
child: Column(
children: [
Container(
width: double.infinity,
height: 100,
child: Card(
color: Colors.blueAccent,
child: Text("Chart"),
),
),
newUsers(addNewUser),
usersList(users)
],
),
));
}
}
Here i have added addNewUserWithSheet method to add bottom sheet.
here is main.dart file (if need)
import 'package:expense_manager/home.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Home(),
);
}
}
Thanx in advance :)
Ahhh I Basically solved it by using Stateful Widget.

Is there solution for images disapearing in flutter after hot reload?

I'm creating a new flutter app, and i want a solution for the images disappearing problem after flutter hot reload.
import 'package:flutter/material.dart';
class Home extends StatefulWidget {
#override
State <StatefulWidget> createState() {
return HomeState();
}
}
class HomeState extends State<Home> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.redAccent,
title: Text('Login Page '),
),
body: Container(
padding: EdgeInsets.all(33.0),
alignment: Alignment.center,
child: Column(
children: <Widget>[
Image.asset('img/userlogin.png'),
Container(
child: Column(
children: <Widget>[
TextField(
controller: null,
decoration: InputDecoration(
icon: Icon(Icons.person), hintText: 'Yor Name'),
)
],
),
)
],
),
),
);
}
}
You could pre-cache the image using preCacheImage function inside you initState methods
like so:
class HomeState extends State<Home> {
#override
void initState() {
precacheImage(new AssetImage('img/userlogin.png'));
super.initState();
}
#override
Widget build(BuildContext context) {
// Widgets...
}
}