I have a tooltip in my UI which has semantics label "Tooltip to know about your number". Below is the code snippet for the same.
Semantics(
label: 'Tooltip to know about your number',
child: InkWell(
child: Image.asset('images/info_selected.png'),
onTap: (){
//some action top show tooltip
},
),
),
When accessibility is ON , and I single tap on info Inkwell, it announce "Tooltip to know about your number" as expected. But my issue here , Its also announcing the same when I double tap.. It should only do the functionality which I wrote inside onTap function when I double tap. What is the best way to make it like , it should not announce when I double tap?
Same code is working fine in android and it announce only when I single tap.. only iOS screen reader is announcing the label on both single tap and double tap..
Same issue when I use Gesture Detector or Button instead of InkWell..
Inkwell have a onTap and onDoubleTap both functions available
Reference - https://api.flutter.dev/flutter/material/InkWell-class.html
Output :-
Code :-
import 'package:flutter/material.dart';
class InkwellExample extends StatefulWidget {
const InkwellExample({Key? key}) : super(key: key);
#override
State<InkwellExample> createState() => _InkwellExampleState();
}
class _InkwellExampleState extends State<InkwellExample> {
String taps = "";
#override
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
return Scaffold(
body: SizedBox(
width: size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
InkWell(
child: const Icon(Icons.info),
onTap: () => setState(() {
taps = "TAP";
}),
onDoubleTap: () => setState(() {
taps = "Double TAP";
}),
),
Text(
taps == "" ? "" : taps,
style: const TextStyle(
fontSize: 24.0,
fontWeight: FontWeight.bold,
),
),
],
),
),
);
}
}
To keep screen readers from reading anything other than what you have in your label parameter, add excludeSemantics: true. So your code would look like this:
Semantics(
label: 'Tooltip to know about your number',
excludeSemantics: true,
child: InkWell(
child: Image.asset('images/info_selected.png'),
onTap: (){
//some action top show tooltip
},
),
),
Another parameter which may be of interest is onTapHint.
One reference I've used:
https://www.woolha.com/tutorials/flutter-using-semantics-mergesemantics-examples
Related
In my flutter application, I have to provide an option to change the font size of the application Text contents.
So, normally, I know that for different screen sizes, We can manage but this is not that case.
I have just gone through this plugin:
https://pub.dev/packages/sizer
But, It's not the case which I am looking for.
The case is to choose particular font size option and according to selected option the font height should be change.
How can I achieve this? Thanks.
If you want the user to be able to change fontsize in your application you could do something like this.
class _MyHomePageState extends State<MyHomePage> {
double? _fontSize = 14;
void _changeFontSize(double fontSize) {
setState(() {
_fontSize = fontSize;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'FontSize is now: $_fontSize',
style: TextStyle(fontSize: _fontSize),
),
ElevatedButton(onPressed: () => _changeFontSize(22), child: const Text("22")),
ElevatedButton(onPressed: () => _changeFontSize(24), child: const Text("24")),
ElevatedButton(onPressed: () => _changeFontSize(26), child: const Text("26")),
],
),
),
);}}
I have a Flutter project that scans barcodes and move the name and barcode and expiration date by the button to the row on another page and this works as expected. But I'm trying to display this row in my home page that contains a ListView and I let inside it some empty list I defined above on the same page.
My question: How can I add the row that contains the name, barcode, and date to the list on my home page when I press the button?
This is the button code:
ElevatedButton(
onPressed: () {
final list = [item_Name.text, item_Barcode.text, date.text];
Provider.of<DataListProvider>(context, listen: false).setData(list);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Details_Item(
name: item_Name.text,
barcode: item_Barcode.text,
dateexpair: date.text,
),
),
);
},
and this is the row page :
class Details_Item extends StatelessWidget {
late String name, barcode;
String dateexpair;
Details_Item(
{required this.name, required this.barcode, required this.dateexpair});
#override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'${name}',
style: TextStyle(fontSize: 13),
),
SizedBox(
width: 70,
),
Text(
'${barcode}',
style: TextStyle(fontSize: 13),
),
SizedBox(
width: 70,
),
Text(
'${dateexpair}',
style: TextStyle(fontSize: 13),
),
],
);
}
}
my home page code :
child: ListView(
children: Container_items,
I think the best option is to implement a model/provider where you can share data between pages. Read the official docs here.
On the other hand, Navigator.pop(context, result) has a result parameter that returns to the caller of await Navigator.push(...). You can use that to pass data between pages.
I am new to Flutter and trying to build a responsive web app. So far, the code I have working is when the screen shrinks in width to a certain size, the navigation bar and its items get crunched into a menu icon button (Flutter's IconButton). This works. What doesn't work is when I click the IconButton, the new navigation bar doesn't pop up, even though the console shows I'm clicking on it. DrawerItem() is just a Text Widget wrapped in a Container. After the couple sections of code, you can see the console spitting out a response. I do not get any errors on screen or in the console when I adjust the screen size or when I click the IconButton. I've also tried making the MNavigationBar a stateful widget and adding setState to the onPressed attribute, nothing changes from the current issue and the same thing happens.
class MNavigationBar extends StatelessWidget {
const MNavigationBar({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
height: 80,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(
Icons.menu,
),
onPressed: () {
NavigationDrawer();
print('Menu Icon pressed');
},
),
NavBarLogo(),
],
),
);
}
}
class NavigationDrawer extends StatelessWidget {
const NavigationDrawer({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
width: 260,
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black,
blurRadius: 16,
),
],
),
child: Column(
children: <Widget>[
NavigationDrawerHeader(),
DrawerItem('Home'),
DrawerItem('Events'),
NavBarMenuDropdown(),
DrawerItem('Store'),
DrawerItem('Partners'),
DrawerItem('About Us'),
],
),
);
}
}
Performing hot restart... 148ms
Restarted application in 149ms.
Menu Icon pressed
Menu Icon pressed
Thank you, Afridi Kayal! I did exactly what you said and it works great! See the answer in the code below...
In my main Scaffold widget, I added this code and also added logic with a ResponsiveBuilder
return ResponsiveBuilder(
builder: (context, sizingInformation) => Scaffold(
drawerEnableOpenDragGesture: false,
drawer: sizingInformation.deviceScreenType == DeviceScreenType.Mobile
? NavigationDrawer()
: null,
In my MNavigationBar, I modified this.
onPressed: () {
Scaffold.of(context).openDrawer();
print('Menu Icon pressed');
},
I'm new to flutter,
So I'm working on a Flutter app & I Have My Functions & Widget File named: 'Function' Separated from my Main but I'm trying to set state in 'Main' from 'Function'
I have tried to set a global variable inside a MyText class Widget inside 'Function' and import 'Main'==> Function & Vice Versa at the same time, but I can't seem to manipulate the GlobalKey variable which would trigger setState again
(Class & MyText class Has since been Scrapped)
I also tried to set the function from my other file to the button like so
floatingActionButton: functions.random()
And somehow was able to set state (Sorry I Forgot How), but it kept running without being pressed
'Main.dart' Sample Code
String display = "";
class _MyHomePageState extends State<MyHomePage> {
var currentScreen = display;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
AutoSizeText(
currentScreen,
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: functions.menu(),
);
} //Build
}// _MyHomePageState
'Function.dart' Sample Code
SpeedDial menu(){
return SpeedDial(
SpeedDialChild(
child: Icon(Icons.autorenew),
backgroundColor: Colors.lightBlueAccent,
label: 'New Activity',
labelStyle: TextStyle(fontSize: 18.0),
onTap: () => random(),
),
)
random(){
...
return someString;
}
Intended Result
When Child 'New Activity' is clicked, setState is called with the variable currentScreen's state being set to the result from the function 'random()'
Thank You In Advance!
I don't know if this can finish your problem, but the approach will be a little different from your approach because I'm not really familiar with the globalsetkey works...
so from my perspective I'm using the bloc pattern so hope this can give you some inspiration how to resolve this problems
in classBLoc.dart
BehaviorSubject<bool> _dialClicked = BehaviorSubject<bool>();
Observable<bool> get dialClicked => _dialClicked.stream;
Function(bool) get dialClickedListener => _dialClicked.sink.add;
in main.dart
section floatingActionButton,
floatingActionButton: functions.menu(currentScreen),
in Function.dart
Widget menu(){
final bloc = Provider.of<classBLoc>();
return StreamBuilder(stream: bloc.dialClicked, initialData: false,builder: (context, snapshot){
return SpeedDial(
SpeedDialChild(
child: Icon(Icons.autorenew),
backgroundColor: Colors.lightBlueAccent,
label: 'New Activity',
labelStyle: TextStyle(fontSize: 18.0),
onTap: () => snapshot.data ? currentScreen : random(), // this used for checking data if have already been clicked or not
);
}),
);
Hope this can you some inspiration how it's worked //sorry if there is wrong bracketed
The widgets in my ReorderableListView are essentially TextFields. When long pressing on a widget, after the time when the long press should cause the widget to "hover," instead the TextField receives focus. How can I make the drag & drop effect take precedence over the TextField? I would still like a normal tap to activate the TextField.
The code below demonstrates my issue.
I also tried to use this unofficial flutter_reorderable_list package. (To test this one, replace the Text widget on this line of the example code with a TextField.)
I'm willing to use any ugly hacks to get this working, including modifying the Flutter source code!
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
final children = List<Widget>();
for (var i = 0; i < 5; i++) {
children.add(Container(
color: Colors.pink, // Only the pink area activates drag & drop
key: Key("$i"),
height: 50.0,
child: Container(
color: Colors.grey,
margin: EdgeInsets.only(left: 50),
child: TextField(),
),
));
}
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: ReorderableListView(
children: children,
onReorder: (oldIndex, newIndex) => null,
),
),
),
);
}
}
You need to do multiple things in there to fix this.
First disable the default handler in ReorderableListView by setting buildDefaultDragHandles: false in its properties.
Wrap you child widget inside ReorderableDragStartListener widget like this
ReorderableDragStartListener(
index: i,
child: Container(
color: Colors.grey,
margin: EdgeInsets.only(left: 50),
child: TextFormField(initialValue: "Child $i", ),
),
),
Then inside this ReorderableDragStartListener wrap your child in InkWell and AbsorbPointer. Then use FocusNode to focus inner TextField on single tap.
Like this
InkWell(
onTap: () => _focusNode.requestFocus(),
onLongPress: () {
print("long pressed");
},
child: AbsorbPointer(
child: TextFormField(initialValue: "Child $i", focusNode: _focusNode,),
),
),
You need to create multiple FocusNode for all the items in list. You can do this by using List or by simpling creating a new FocusNode inside the loop.
Complete code example here https://dartpad.dev/?id=e75b493dae1287757c5e1d77a0dc73f1