Keyboard immediately disappear when onTap event fired in Flutter - android

I'm developing a flutter app using Bloc, Division, and Get for the navigation.
I have a text field reusable component that I use in most of the fields that I create, the text field works properly on iOS without any issues, but on Android the Keyboard immediately disappear when I tap the field.
Here are the things that I've done but it still doesn't work:
Not using text field from the component, but directly create another one on the page
Create my own testing page that only used to test the text field
Using resizeToAvoidBottomInset: false, defined the controller as a static final
The only thing that works is when I create another flutter project from the start.
my-testing.dart
import 'package:flutter/material.dart';
class MyTesting extends StatefulWidget {
const MyTesting({Key? key}) : super(key: key);
#override
State<MyTesting> createState() => _MyTestingState();
}
class _MyTestingState extends State<MyTesting> {
late TextEditingController controller;
#override
void initState() {
controller = TextEditingController();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Just testing'),
),
body: Padding(
padding: const EdgeInsets.all(20),
child: TextField(
controller: controller,
),
),
);
}
}

Related

Issue creating a button variable in Flutter

I am currently using flutter for an android app and I am using the "Routegenerator.dart" method for navigating . In this project, a certain button gets repeated multiple times and always leads to the same page. I want to create a variable of this button to clean the code a bit and avoid myself useless repetitions. The issue here is that I need to put the variable after the class with the scaffold, and this causes the Navigator.of(context).pushNamed() to give me an error in the (context).
How to solve this issue please?
you can call TextButtonWidget anywhere in your screen like this:
TextButtonWidget(
onTap: (){
Navigator.of(context).pushNamed('anyScreen');
},),
Import this widget
import 'package:flutter/material.dart';
class TextButtonWidget extends StatelessWidget {
const TextButtonWidget({
Key? key,
required this.onTap,
}) : super(key: key);
final VoidCallback onTap;
#override
Widget build(BuildContext context) {
ThemeData _theme = Theme.of(context);
return Material(
color: Colors.transparent,
child: InkWell(
onTap: onTap,
child: Container(
padding: const EdgeInsets.all(8.0),
child: const Text('Choose me')),
),
);
}
}

Flutter - losing state when pressing back button to android home screen

I have an issue with flutter. I have managed to implement a basic navigation system that keeps state when you do either of the following:
switch between tabs
press the android home button and re-open the app (either by clicking on the app again or using the list of active app button (the little square at the bottom))
But if I press the back button - going back to the android homescreen I completely lose state. I have re-implemented some code to randomly generate a number and display it on the app - this way I know if I'm getting the same widget or a new one has been built.
Why do I need this? (if you're interested)
I'm creating an audio app and when I click play song, it plays. but when I click back to the home screen and let it play in the background -> then open the app again, I can play it again and have it playing twice!
Main:
import 'package:flutter/material.dart';
import 'BottomNavigationBarController.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Login',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: BottomNavigationBarController(),
);
}
}
Bottom navigation tab (BottomNavigationBarController):
import 'package:flutter/material.dart';
import 'PlaceholderWidget.dart';
class BottomNavigationBarController extends StatefulWidget {
BottomNavigationBarController({Key key}) : super(key: key);
#override
_BottomNavigationBarController createState() => _BottomNavigationBarController();
}
class _BottomNavigationBarController extends State<BottomNavigationBarController>{
int _selectedPage = 0;
List<Widget> pageList = List<Widget>();
#override
void initState() {
pageList.add(PlaceholderWidget());
pageList.add(PlaceholderWidget());
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: IndexedStack(
index: _selectedPage,
children: pageList,
),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.phone_android),
title: Text('First Page'),
),
BottomNavigationBarItem(
icon: Icon(Icons.phone_android),
title: Text('Second Page'),
),
],
currentIndex: _selectedPage,
selectedItemColor: Colors.blue,
onTap: _onItemTapped,
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
void _onItemTapped(int index) {
setState(() {
_selectedPage = index;
});
}
}
Random number widget (PlaceholderWidget):
import 'dart:math';
import 'package:flutter/material.dart';
class PlaceholderWidget extends StatefulWidget {
PlaceholderWidget({Key key, this.color}) : super(key: key);
final Color color;
#override
_PlaceholderWidget createState() => _PlaceholderWidget();
}
class _PlaceholderWidget extends State<PlaceholderWidget> with AutomaticKeepAliveClientMixin {
#override
bool get wantKeepAlive => true;
#override
Widget build(BuildContext context) {
return Container(
color: widget.color,
child: Text(random_num().toString()),
);
}
int random_num(){
Random random = new Random();
int randomNumber = random.nextInt(100);
return randomNumber;
}
}
Any help will be appreciated :)
I think Navigator pop deletes the widget not entirely sure. But If you want to save the current state just use navigator push don't pop. Also use named routes this will help you greatly.
Use Provider to pass state and keep a global store.
If your app will need to scale, now is a good time to start with MobX/BLoC/Redux/InheritedWidget.. etc.

Why doesn't anything show up the body of this flutter scaffold?

The class in question is invoked from another page with the line
onPressed: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) =>
ProPage(iD: bestRatedPros[index]["ID"])));
},
Where bestRatedPros is a list of maps with the variable iD for the following class -
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class ProPage extends StatefulWidget {
ProPage({Key key, this.iD}) : super(key: key);
final iD;
#override
_ProPageState createState() => _ProPageState(iD);
}
class _ProPageState extends State<ProPage> {
int iD;
_ProPageState(this.iD);
#override
void initState() {
super.initState();
}
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.amber,
extendBodyBehindAppBar: true,
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.white, //change your color here
),
elevation: 0,
backgroundColor: Colors.amber
),
body:
Text("EWFWEFEWEWFWEF",style: TextStyle(color: Colors.black))
);
}
}
The getDataFromBackend function and
all the variables associated with it was meant to be within the body. But Nothing shows up in the body no matter what it is. Even a simple Text widget doesn't. I'm only trying to pass the variable iD from one page to the other without complicating things. The Run log doesn't show any Errors or warnings.
Arun,
See below where your Text is:
Reason for that is that you specified:
extendBodyBehindAppBar: true,
on your Scaffold, so body is expanded and top part of it is hidden behind AppBar

Navigation to sub-screen from BottomNavigationBar-sceeen in Flutter

I´m currently working on my first simple flutter application and am trying to figure our the best approach to handle the navigation between screens.
Already Possible:
Navigation through screens with BottomNavigationBar + BottomNavigationBarItem
Navigation with Navigator.push(context,MaterialPageRoute(builder: (context) => Screen4()),);
Problem:
Having sub-screens in the screens of BottomNavigationBar
Code Example:
I want to have three main screens Screen1(), Screen2() and Screen3() accessible from the BottomNavigationBar. In Screen1() there is a button to navigate to another screen, let´s call it Screen4(), where the user can choose from a list of items. You can then add all chosen items to a list and navigate back to Screen1().
To achieve this I created the code below. The main Widget of the body will be changed according to the current index of the selected BottomNavigationItem.
main.dart
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
static const String _title = 'Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: MyApp(),
);
}
}
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int _selectedIndex = 0;
static const List<Widget> _widgetOptions = <Widget>[
Screen1(),
Screen2(),
Screen3(),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Stackoverflow Example'),
),
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Screen1'),
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
title: Text('Screen2'),
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
title: Text('Screen3'),
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
),
);
}
}
The problem is when I navigate within the Screen1() - Widget to Screen4() by using
Navigator.push(context,MaterialPageRoute(builder: (context) => Screen4()),);
the navigation will happen outside of MyApp() and therefore there is no Scaffold.
If someone has an example, where this is achieved I´d be very happy.
Thank you for reading.
I know it's a bit late, but hopefully, it can help you.
To achieve this you can use the Offstage widget with a navigator as its child, this way you will have a persistent navigation bar throughout all of your pages.
you can follow this article for more details and how to implement it
https://medium.com/coding-with-flutter/flutter-case-study-multiple-navigators-with-bottomnavigationbar-90eb6caa6dbf
you might need to tweak it a little to match your case.
info about the Offstage widget:
https://api.flutter.dev/flutter/widgets/Offstage-class.html
I suggest that you run a CupertinoApp instead of a MaterialApp. Use a CupertinoTabScaffold instead of Scaffold. Add a CupertinoTabBar as tabBar and return a CupertinoTabView as a tabBuilder
example of tabBuilder
tabBuilder: (context, index) {
if (index == 0) {
return CupertinoTabView(
navigatorKey: firstTabNavKey,
builder: (BuildContext context) => Screen1(),
Have a look at this great short article on how to implement a Tab Bar and also allow for Navigation between screens: link

Flutter hide onscreenkeyboard on android Barcode Scanner

iam developing a Flutter app to acquire numbers via an extrernal Bluetooth Scanner which acts like a normal Keyboard.
If i tap on the TextInputField the native android Keyboard pops up to enter text, which is fine, but i need to supress the keyboard since iam going to scan Barcodes and i need the full Screen to see my scanned Barcodes.
#Barcodes: these are only 12-digit long numbers.
so far,
axp
//I created this solution based it works for iOS and Android both.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class QRCodeScreen extends StatefulWidget {
QRCodeScreen({Key key}) : super(key: key);
#override
_QRCodeScreenState createState() => _QRCodeScreenState();
}
class _QRCodeScreenState extends State<QRCodeScreen> {
FocusNode node = NoKeyboardEditableTextFocusNode();
TextEditingController scanController = TextEditingController();
#override
void initState() {
node.requestFocus();
Future.delayed(
const Duration(milliseconds: 300),
() {
SystemChannels.textInput.invokeMethod('TextInput.invisible');
}
);
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Container(
child: IgnorePointer(
child: Padding(
padding: const EdgeInsets.all(5.0),
child: Column(
children: [
TextField(
controller: scanController,
focusNode: node,
autofocus: true,
decoration: InputDecoration(hintText: "WAITING FOR QR CODE..."),
),
SizedBox(height:50),
],
),
),
),
),
);
}
#override
void dispose() {
node.dispose();
super.dispose();
}
}
class NoKeyboardEditableTextFocusNode extends FocusNode {
#override
bool consumeKeyboardToken() {
return false;
}
}
My scanner is an Android phone, here is what I've done:
Implemented Kotlin code to hide keyboard
Created a method channel
Invoke method in Flutter where I needed to hide soft keyboard
https://github.com/flutter/flutter/issues/44681#issuecomment-962110920

Categories

Resources