flutter I want to convert NumberFormat form to double - flutter

Below is the code where the error occurs.
I want to convert [NumberFormat][1] form to double. What should I do?
I want to display it on the screen with the currency symbol, and get the result as a double .
Sample source:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class ProductEditor extends StatefulWidget {
const ProductEditor({Key? key}) : super(key: key);
#override
_ProductEditorState createState() => _ProductEditorState();
}
class _ProductEditorState extends State<ProductEditor> {
final NumberFormat euNumFormat =
NumberFormat.currency(locale: 'eu_EU', symbol: '€');
TextEditingController _ctrPrice = TextEditingController();
double _price = 25000.00;
#override
void initState() {
super.initState();
_ctrPrice.text = euNumFormat.format(_price); //
}
#override
Widget build(BuildContext context) {
return Container(
width: 500,
height: 300,
child: TextField(
controller: _ctrPrice,
onSubmitted: (String price) {
setState(() {
final double value = double.tryParse(_ctrPrice.text
.substring(0, _ctrPrice.text.length - 2)
.replaceAll(',', '')) ??
0.0;
print('price:${_ctrPrice.value.toString()} ${value}');
final formattedPrice = euNumFormat.format(value);
_ctrPrice.value = TextEditingValue(
text: formattedPrice,
selection: TextSelection.collapsed(offset: formattedPrice.length),
);
});
},
),
);
}
}

You can create a substring by removing symbol and , from there, then parse it.
final double retailPrice = double.tryParse(
_ctrPrice.substring(0, _ctrPrice.length - 2).replaceAll(",", ''),
) ??
0.0;
This solution only work on specific number format('eu_EU').

Related

Flutter null safety migration error Null check operator used on a null value - occured at PageTransformer ScrollMetrics object

I implemented PageView parallax effects in Flutter using github repo page-transformer .
After Null safety migration I am facing the error below.
======== Exception caught by widgets library =======================================================
The following _CastError was thrown building PageTransformer(dirty, state: _PageTransformerState#a4851):
Null check operator used on a null value
I am relatively new to Dart and Flutter, and I know very little about ScrollMetrics
Below is the code file of page_transformer.dart
import 'package:flutter/material.dart';
import 'package:meta/meta.dart';
/// A function that builds a [PageView] lazily.
typedef PageView PageViewBuilder(
BuildContext context, PageVisibilityResolver visibilityResolver);
/// A class that can be used to compute visibility information about
/// the current page.
class PageVisibilityResolver {
PageVisibilityResolver({
ScrollMetrics? metrics,
double? viewPortFraction,
}) : this._pageMetrics = metrics!, //Error here <----- When the exception was thrown, this was the stack: #0 new PageVisibilityResolver
this._viewPortFraction = viewPortFraction!;
final ScrollMetrics _pageMetrics;
final double _viewPortFraction;
PageVisibility resolvePageVisibility(int pageIndex) {
final double pagePosition = _calculatePagePosition(pageIndex);
final double visiblePageFraction =
_calculateVisiblePageFraction(pageIndex, pagePosition);
return PageVisibility(
visibleFraction: visiblePageFraction,
pagePosition: pagePosition,
);
}
double _calculateVisiblePageFraction(int index, double pagePosition) {
if (pagePosition > -1.0 && pagePosition <= 1.0) {
return 1.0 - pagePosition.abs();
}
return 0.0;
}
double _calculatePagePosition(int index) {
final double viewPortFraction = _viewPortFraction ?? 1.0;
final double pageViewWidth =
(_pageMetrics?.viewportDimension ?? 1.0) * viewPortFraction;
final double pageX = pageViewWidth * index;
final double scrollX = (_pageMetrics?.pixels ?? 0.0);
final double pagePosition = (pageX - scrollX) / pageViewWidth;
final double safePagePosition = !pagePosition.isNaN ? pagePosition : 0.0;
if (safePagePosition > 1.0) {
return 1.0;
} else if (safePagePosition < -1.0) {
return -1.0;
}
return safePagePosition;
}
}
/// A class that contains visibility information about the current page.
class PageVisibility {
PageVisibility({
required this.visibleFraction,
required this.pagePosition,
});
final double visibleFraction;
final double pagePosition;
}
class PageTransformer extends StatefulWidget {
PageTransformer({
required this.pageViewBuilder,
});
final PageViewBuilder pageViewBuilder;
#override
_PageTransformerState createState() => _PageTransformerState();
}
class _PageTransformerState extends State<PageTransformer> {
PageVisibilityResolver? _visibilityResolver;
#override
Widget build(BuildContext context) {
final pageView = widget.pageViewBuilder(
context, _visibilityResolver ?? PageVisibilityResolver());
final controller = pageView.controller;
final viewPortFraction = controller.viewportFraction;
return NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification notification) {
setState(() {
_visibilityResolver = PageVisibilityResolver(
metrics: notification.metrics,
viewPortFraction: viewPortFraction,
);
});
return false; //need a check
},
child: pageView,
);
}
}
Below is the code file of intro_page_view.dart
import 'dart:math';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:tailor_ai/screens/main/main_page.dart';
import 'package:tailor_ai/screens/product/product_page.dart';
import 'package:flutter/material.dart';
import 'package:tailor_ai/models/product.dart';
import 'page_transformer.dart';
import 'intro_page_item.dart';
class IntroPageView extends StatelessWidget {
final List<Product>? product;
final _controller = new PageController(viewportFraction: 0.85);
static const _kDuration = const Duration(milliseconds: 300);
static const _kCurve = Curves.ease;
final _kArrowColor = Colors.black.withOpacity(0.8);
IntroPageView({Key? key,this.product}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SizedBox.fromSize(
size: const Size.fromHeight(500.0),
child: PageTransformer( //<-------------- The relevant error-causing widget was: PageTransformer PageTransformer
pageViewBuilder: (context, visibilityResolver) {
return PageView.builder(
controller: _controller,
itemCount: product!.length,
itemBuilder: (context, index) {
//final item = product;
final pageVisibility =
visibilityResolver.resolvePageVisibility(index);
return InkWell(
onTap: () => Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => ProductPage(
product: product![index]
))),
child: Stack(
children: <Widget>[
IntroPageItem(product: product![index], pageVisibility: pageVisibility),
],
),
);
},
);
},
),
),
),
);
}
}
you can find the entire code files for page_transformer project in above mentioned github link which is not updated for null safety.
terminal screenshot for reference
Your valuable time in response would be much appreciated.
Here is the problem, you have this variable: final ScrollMetrics _pageMetrics; which is not nullable, on initialization, you assign it to this other variable ScrollMetrics? metrics, which is nullable. The error you get happened because metrics was null and you tried to assign it to _pageMetrics.
So why is metrics null? Well, you are supposed to pass the value of metrics on the constructor, but you didn't on this line:
final pageView = widget.pageViewBuilder(
context, _visibilityResolver ?? PageVisibilityResolver());
So the solution is to either make _pageMetrics nullable or to pass metrics to the constructor.
Pro tip: When you have a named parameter on your constructor that should always be passed (that is to say, it should never be null) you can use the required keyword:
PageVisibilityResolver({
required ScrollMetrics metrics,
required double viewPortFraction,
}) : this._pageMetrics = metrics,
this._viewPortFraction = viewPortFraction;
Of course you could also give them a default value.

how to save controller.index value into a static variable?

class SignUpConvert extends StatefulWidget {
const SignUpConvert({ Key? key}) : super(key: key);
#override
_SignUpConvertState createState() => _SignUpConvertState();
}
class _SignUpConvertState extends State<SignUpConvert>
with SingleTickerProviderStateMixin {
TabController? tabController;
#override
void initState() {
super.initState();
tabController = TabController(vsync: this, length: 2);
print(tabController!.index);
}
#override
void dispose() {
super.dispose();
}
I want to reflect the current index in a static variable
class MyVariable{
static int indexCount = 0;
}
so that i can use it to navigate from a same button to different pages
the button is;
onSubmit: (_) {
if (MyVariable.indexCount == 0) {
Navigator.of(context).push(MaterialPageRoute(
builder: (builder) => LogInConvert()));
}
else if (MyVariable.indexCount == 1) {
Navigator.of(context).push(MaterialPageRoute(
builder: (builder) => SignUpConvert()));
}
},
but the controller.index is not saving in MyVariable.indexCount and i'm getting the default value i.e 0.
i am saving index using custom button
CustomButton(
index: widget.tabIndex,
route: widget.pageToNavigate,
backgroundColor: Color(0xff416bbd),
borderColor: Color(0xff416bbd),
name: 'Sign Up',
textColor: Colors.white,
),
the index value is then assigned to MyVariable.indexCount.
but it is not working!!
Use getx Storage to store the static value and read the value and getstorage.read("store");
dependencies:
get_storage: ^2.0.3
example:
static final _otherBox = () => GetStorage('MyPref');
final username = ''.val('username');
final age = 0.val('age');
final price = 1000.val('price', getBox: _otherBox);
// or
final username2 = ReadWriteValue('username', '');
final age2 = ReadWriteValue('age', 0);
final price2 = ReadWriteValue('price', '', _otherBox);

Change color part of text using index in flutter

I have a one String which contains words: achievement admission advertise pencil. I have a list with pairs of numbers:
class Pair<T1, T2> {
final T1 a;
final T2 b;
Pair(this.a, this.b);
}
String letters = "achievement admission advertise pencil";
List<Pair> words = [Pair(3, 5), Pair(6, 8), Pair(9, 11), Pair(12, 14), Pair(15, 17)];
I want to change color part of String using index from which sign to which sign. For example after 2 seconds letters from 3 to 5 should have color green. After next 2 seconds only letters from 6 to 8 should be green, after next 2 seconds only letters from 9 to 11 should be green, rest letters should return to black. There is any way to do that?
Yes, you can create a custom widget for this. Here is a working example:
(Use with SyllableText(text: letters, parts: words))
class SyllableText extends StatefulWidget {
const SyllableText({
required this.text,
required this.parts,
Key? key,
}) : super(key: key);
final String text;
final List<Pair> parts;
#override
SyllableTextState createState() => SyllableTextState();
}
class SyllableTextState extends State<SyllableText> {
int currentPartIndex = 0;
#override
void initState() {
super.initState();
Future.doWhile(() async {
await Future.delayed(Duration(seconds: 2));
if (mounted && currentPartIndex < widget.parts.length) {
setState(() => currentPartIndex++);
return true;
} else {
return false;
}
});
}
#override
Widget build(BuildContext context) {
if (currentPartIndex < widget.parts.length) {
final part = widget.parts[currentPartIndex];
final startText = widget.text.substring(0, part.a);
final coloredText = widget.text.substring(part.a, part.b + 1);
final endText = widget.text.substring(part.b + 1);
return Text.rich(
TextSpan(
children: [
TextSpan(text: startText),
TextSpan(text: coloredText, style: TextStyle(color: Colors.green)),
TextSpan(text: endText),
],
),
);
} else {
return Text(widget.text);
}
}
}

flutter [Only static members can be accessed in initializers]

I am a true beginner in flutter and dart.
I have a problem concerning playing youtube videos using [ youtube_player_flutter: ^6.1.1]
I create a Json file with youtube links and I want to link it with [ youtube_player_flutter: ^6.1.1]. but it always displays the error message [Only static members can be accessed in initializers]
#override
Widget build(BuildContext context) {
// this function is called before the build so that
// the string assettoload is avialable to the DefaultAssetBuilder
setasset();
// and now we return the FutureBuilder to load and decode JSON
return FutureBuilder(
future:
DefaultAssetBundle.of(context).loadString(assettoload, cache: true),
builder: (context, snapshot) {
List mydata = json.decode(snapshot.data.toString());
if (mydata == null) {
return Scaffold(
body: Center(
child: Text(
"Loading",
),
),
);
} else {
return quizpage(mydata: mydata);
}
},
);
}
}
class quizpage extends StatefulWidget {
final dynamic mydata;
////////var youtubeUrl;
quizpage({Key key, #required this.mydata}) : super(key: key);
#override
_quizpageState createState() => _quizpageState(mydata);
}
class _quizpageState extends State<quizpage> {
var mydata;
_quizpageState(this.mydata);
int marks = 0;
int i = 1;
#override
void setState(fn) {
if (mounted) {
super.setState(fn);
}
}
YoutubePlayerController _controller;
#override
void initState() {
_controller = YoutubePlayerController(
initialVideoId: YoutubePlayer.convertUrlToId(mydata[4]["1"]));
super.initState();
}
void nextquestion() {
setState(() {
if (i < 10) {
i++;
} else {
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => resultpage(marks: marks),
));
}
The problem is that I want to make the [String videoURL ] plays the list of videos in my json data file.
Thanks in advance.
Possibility is that you coded the variable mydata twice. This is the format you should follow. And in order to make use of the variable from the StatefulWidget from the constructor, use widget.mydata. Don't have to declare it twice.
Code:
class Quizpage extends StatefulWidget {
final dynamic mydata;
quizpage({Key key, #required this.mydata}) : super(key: key);
#override
_QuizpageState createState() => _QuizpageState();
}
class _QuizpageState extends State<Quizpage> {
/*
You can make use of your mydata in this class like this:
widget.mydata, and you will be able to make it work
*/
Color colortoshow = Colors.indigoAccent;
Color right = Colors.green;
Color wrong = Colors.red;
int marks = 0;
int i = 1;
// String videoURL ="https://www.youtube.com/watch?v=2OAdfB2U88A&t=593s";
YoutubePlayerController _controller;
// Use like this to make use of your array mydata
String videoURL = widget.myData[4]["1"];
#override
void initState() {
_controller = YoutubePlayerController(
initialVideoId: YoutubePlayer.convertUrlToId(videoURL));
super.initState();
}
}
Also, this is for coding point of view. Please follow the correct way of naming classes in Flutter. Always use CamelCase or Have your first letter of the class as capital. This is the best practice while you write your code. I hope the above helps you in some sense. Thanks :)

Flutter Widget that shows text line by line?

Is there a widget in Flutter that allows children Text widgets to be shown line by line at every press of the widget? This should act similar to how bulleted lines in a powerpoint presentation act after every click.
I just tested and it works, probably I did not cover some edge cases, but it is not a lot of work...
//I would call it TIM like VIM :P
class TextIMproved extends StatefulWidget {
final String _longString;
final int _numberOfWordsPerRow;
TextIMproved(this._numberOfWordsPerRow, this._longString);
#override
_TextIMprovedState createState() => _TextIMprovedState(_numberOfWordsPerRow, _longString);
}
class _TextIMprovedState extends State<TextIMproved> {
final String longString;
List<String> listString;
int _numberOfWordsPerRow;
String strPopulated;
String strToDisplay='';
_TextIMprovedState(this._numberOfWordsPerRow, this.longString);
#override
void initState() {
super.initState();
listString = longString.split(' ');
splitString();
}
#override
Widget build(BuildContext context) {
return GestureDetector(
child: Container(
child: Text(strToDisplay, maxLines: longString.length ~/ _numberOfWordsPerRow + _numberOfWordsPerRow,),
),
onTap: splitString,
);
}
void splitString() {
//1.prepare empty string
strPopulated = '';
//2.populate string
int len = listString.length <_numberOfWordsPerRow ? listString.length : _numberOfWordsPerRow;
for (int i = 0; i < len; i++) {
strPopulated += listString[i] + ' ';
}
//3. display portion of string
setState(() {
strToDisplay += strPopulated;
});
//4.remove displayed text
List<String> listToremove = strPopulated.split(' ');
for (String str in listToremove) {
listString.remove(str);
}
}
}
EDIT:
you can add animation to this widget...