Using a string to access a get method in themes - flutter

So basically, I want to be able to use a line of code like:
body: Container(
height: getDimension(context, true, 'homeContainer');
)
but I don't know how I would go about using the String type to access the data in my theme extension.
extension CustomDimensions on MaterialTapTargetSize {
//double get 'name' => 'dimension';
double get 'homeContainer' => 1.0;
}
double getDimension(BuildContext context, bool isHeight, String type) {
double value;
isHeight ? value = MediaQuery.of(context).size.height * Theme.of(context).textTheme.$type : null;
return value;
}

extension CustomDimensions on TextTheme {
double type({String data}) {
if(data == 'homeContainer')
return 1.0;
else
return 0; // else code
}
}
double getDimension(BuildContext context, bool isHeight, String type) {
double value;
isHeight ? value = MediaQuery.of(context).size.height * Theme.of(context).textTheme.type(data: type) : null;
return value;
}

Related

my code not complete for where contact number

How to fix code my code flutter and use plugin
filterContacts() {
setState(() {
List<Contact> _contacts = [];
_contacts.addAll(contacts);
if (searchController.text.isNotEmpty) {
_contacts.retainWhere(
(contact) {
String searchTerm = searchController.text.toLowerCase().trim();
String searchTermFlatten = flattenPhoneNumber(searchTerm);
String contactName = contact.displayName.toString().toLowerCase();
bool nameMatches = contactName.contains(searchTerm);
if (nameMatches == true) {
return true;
}
if (searchTermFlatten.isEmpty) {
return false;
}
var phone = contact.phones.firstWhere((phn) {
String phnFlattened = flattenPhoneNumber(phn);
return phnFlattened.contains(searchTermFlatten);
}, orElse: () => null);
return phone != null;
},
);
contactsFiltered = _contacts;
}
});
}
Flutter code How to fix code my code flutter and use plugin contacts_service,
this image is about a problem
contact.phones can be null, in this you need to check its value 1st then proceed,
you can use contact.phones?.firstWhere to handle this situation or
If you're sure it will have value, you can also do contact.phones!.firstWhere but I don't recommend this. You don't need to use orElse you want to pass null,
Item? phone = contact.phones?.firstWhere((phn) {
String phnFlattened = flattenPhoneNumber(phn);
return phnFlattened.contains(searchTermFlatten);
}, );
You can learn more about ?. !...
[how to fix now]
error code not complete
filterContacts() {
setState(() {
List<Contact> _contacts = [];
_contacts.addAll(contacts);
if (searchController.text.isNotEmpty) {
_contacts.retainWhere(
(contact) {
String searchTerm = searchController.text.toLowerCase().trim();
String searchTermFlatten = flattenPhoneNumber(searchTerm);
String contactName = contact.displayName.toString().toLowerCase();
bool nameMatches = contactName.contains(searchTerm);
if (nameMatches == true) {
return true;
}
if (searchTermFlatten.isEmpty) {
return false;
}
Item? phone = contact.phones?.firstWhere((phn) {
String phnFlattened = flattenPhoneNumber(phn);
return phnFlattened.contains(searchTermFlatten);
}, );
return phone != null;
},
);
contactsFiltered = _contacts;
}
});
}

Expected a value of type 'string' but got one of type 'int' - Flutter

I have a function that returns a String, but when I call this function, the app screen goes red and I get this error: Expected a value of type 'string' but got one of type 'int'.
Here is my function that returns a String:
checkProportion(String predominantGamete, String resultado) {
var countBrown = 0;
var countBlack = 0;
var countWhite = 0;
var proportionCamundongo =
'Proporção: ${countBrown}:${countBlack}:${countWhite}';
if (predominantGamete == 'recessiva_aa' &&
resultado.contains('A') &&
resultado.contains('P')) {
return countBrown += 1;
} else if (predominantGamete == 'recessiva_aa' &&
resultado.contains('A') &&
resultado.contains('pp')) {
return countBlack += 1;
} else if (predominantGamete == 'recessiva_aa' &&
resultado.contains('aa')) {
return countWhite += 1;
}
return proportionCamundongo;
}
Here is how I call the function:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
title: Text(
checkProportion(widget.predominant, widget.result),
),
),
How to solve this error?
Here is an image that shows the colors of each result:
The issue here is that you are returning early, not breaking the if statement, when you do something like return countBrown += 1;;
Try incrementing the counters, then using string interpolation to display the value:
String checkProportion(String predominantGamete, String resultado) {
int countBrown = 0;
int countBlack = 0;
int countWhite = 0;
if (predominantGamete == 'recessiva_aa' &&
resultado.contains('A') &&
resultado.contains('P')) {
countBrown += 1;
} else if (predominantGamete == 'recessiva_aa' &&
resultado.contains('A') &&
resultado.contains('pp')) {
countBlack += 1;
} else if (predominantGamete == 'recessiva_aa' &&
resultado.contains('aa')) {
countWhite += 1;
}
return 'Proporção: ${countBrown}:${countBlack}:${countWhite}';
}
I'd also recommend specifing the return type of the function (String), using the correct types for counters (int). That will help your compiler catch the issues as well.
It isn't my best work, and there is probably a better way to check for if a string contains all occurrence of multiple substrings, but here you go:
bool isColorContained(String resultado, Set<String> requirements) {
for(String requirement in requirements) {
if (!resultado.contains(requirement)) {
return false;
}
}
return true;
}
 
String checkProportion(String predominantGamete, String resultado) {
Map<ColorType, Set<String>> colorType = {
ColorType.brown: {'A', 'P'},
ColorType.black: {'A', 'pp'},
ColorType.white: {'aa'},
};
Map<ColorType, int> colorTypeCount = {
ColorType.brown: 0,
ColorType.black: 0,
ColorType.white: 0,
};
for(MapEntry<ColorType, Set<String>> entry in colorType.entries ) {
if(predominantGamete != 'recessiva_aa') continue;
bool contained = isColorContained(resultado, entry.value);
if(contained) {
int count = colorTypeCount[entry.key] ?? 0;
colorTypeCount[entry.key] = count + 1;
}
}
return 'Proporção: ${colorTypeCount[ColorType.brown]}:${colorTypeCount[ColorType.black]}:${colorTypeCount[ColorType.white]}';
}
 
Also, declare the ColorType enum:
enum ColorType {
brown, black, white
}
This will scale with as many colors and requirements you have, by adding to the ColorType enum, the colorType map, and the colorTypeCount map.

Reusing input validator

I'm trying to create a logic for reusing multiple input validator at once. Here is DartPad code
void main() {
String value = 'pppppp';
print(InputValidator([InputValidator.minCharacters(value, 2),
InputValidator.maxCharacters(value, 5)
]).validate().toString());
}
class InputValidator {
final List<String> validators;
InputValidator(this.validators);
List<String> validate() {
List<String> result = [];
validators.where((s) => s != null).forEach(result.add);
return result;
}
static String maxCharacters(String value, int limit) {
if (value.length > limit) {
return 'Max $limit characters allowed';
}
return null;
}
static String minCharacters(String value, int limit) {
if (value.length < limit) {
return 'Min $limit characters required';
}
return null;
}
}
the logic works great however I'm trying to make it even easier where I wouldn't need to pass value into each method. I want to make value parameter in InputValidator class and take that value when running a method. Problem is that each method is static so I can not use that parameter in method.. Is there any other way?
Here is how I would like to use it
validator: InputValidator(value, [InputValidator.minCharacters(2),
InputValidator.maxCharacters(5)
]).validate()
Once again thanks to #pskink where he pointed out on FormFieldValidator. With that it is very simple to reuse validating of TextFormField.
Here is validator class
FormFieldValidator<String> all(Iterable validators) {
return (String s) {
var error = validators
.map((v) => v(s))
.where((error) => error != null)
.join(' AND ');
return error.isEmpty? null : error;
};
}
FormFieldValidator<String> uppercase() {
return (String s) => s.startsWith(RegExp('[A-Z]'))? null : 'does not start with uppercase' ;
}
FormFieldValidator<String> limit(min, max) {
return (String s) => (min <= s.length && s.length <= max)? null : 'length not in range [$min..$max]';
}
and here how to use it
Column(
children: [
Form(key: _formKey, child: TextFormField(validator:all([limit(2,5), uppercase()]))),
FlatButton(child:Text('Validate'), onPressed: (){if(_formKey.currentState.validate())
{print('OK');}}),
],
);

Format string to phone number with (123) 456-6789 pattern using dart

Here is my code
void main() {
String phoneNumber = '123456789';
String formattedPhoneNumber = phoneNumber.replaceFirst("(\d{3})(\d{3})(\d+)", "(\$1) \$2-\$3");
print('Formatted number ${formattedPhoneNumber}');
}
Output:
Formatted number 123456789
I want output as Formatted number (123) 456-6789
Try this
print('1234567890'.replaceAllMapped(RegExp(r'(\d{3})(\d{3})(\d+)'), (Match m) => "(${m[1]}) ${m[2]}-${m[3]}"));
Create a custom Masked class
import 'package:flutter/material.dart';
class MaskedTextController extends TextEditingController {
MaskedTextController({String text, this.mask, Map<String, RegExp> translator})
: super(text: text) {
this.translator = translator ?? MaskedTextController.getDefaultTranslator();
this.addListener(() {
var previous = this._lastUpdatedText;
if (this.beforeChange(previous, this.text)) {
this.updateText(this.text);
this.afterChange(previous, this.text);
} else {
this.updateText(this._lastUpdatedText);
}
});
this.updateText(this.text);
}
String mask;
Map<String, RegExp> translator;
Function afterChange = (String previous, String next) {};
Function beforeChange = (String previous, String next) {
return true;
};
String _lastUpdatedText = '';
void updateText(String text) {
if(text != null){
this.text = this._applyMask(this.mask, text);
}
else {
this.text = '';
}
this._lastUpdatedText = this.text;
}
void updateMask(String mask, {bool moveCursorToEnd = true}) {
this.mask = mask;
this.updateText(this.text);
if (moveCursorToEnd) {
this.moveCursorToEnd();
}
}
void moveCursorToEnd() {
var text = this._lastUpdatedText;
this.selection = new TextSelection.fromPosition(
new TextPosition(offset: (text ?? '').length));
}
#override
void set text(String newText) {
if (super.text != newText) {
super.text = newText;
this.moveCursorToEnd();
}
}
static Map<String, RegExp> getDefaultTranslator() {
return {
'A': new RegExp(r'[A-Za-z]'),
'0': new RegExp(r'[0-9]'),
'#': new RegExp(r'[A-Za-z0-9]'),
'*': new RegExp(r'.*')
};
}
String _applyMask(String mask, String value) {
String result = '';
var maskCharIndex = 0;
var valueCharIndex = 0;
while (true) {
// if mask is ended, break.
if (maskCharIndex == mask.length) {
break;
}
// if value is ended, break.
if (valueCharIndex == value.length) {
break;
}
var maskChar = mask[maskCharIndex];
var valueChar = value[valueCharIndex];
// value equals mask, just set
if (maskChar == valueChar) {
result += maskChar;
valueCharIndex += 1;
maskCharIndex += 1;
continue;
}
// apply translator if match
if (this.translator.containsKey(maskChar)) {
if (this.translator[maskChar].hasMatch(valueChar)) {
result += valueChar;
maskCharIndex += 1;
}
valueCharIndex += 1;
continue;
}
// not masked value, fixed char on mask
result += maskChar;
maskCharIndex += 1;
continue;
}
return result;
}
}
Now call it in your main dart file
var maskedController = MaskedTextController(mask: '(000) 000-0000');
TextField(
controller: maskedController,
style: Styles.textNormalStyle,
maxLines: 1,
),
This solution work for your this specific Question and scenario.
you can achieve using following code.
String formattedPhoneNumber = "(" + phoneNumber.substring(0,3) + ") " +
phoneNumber.substring(3,6) + "-" +phoneNumber.substring(6,phoneNumber.length);
Ricardo pointed to a great library but his answer is half right. Besides the intl_phone_number_input you need to get libphonenumber_plugin installed as well.
intl_phone_number_input: ^0.7.0+2
libphonenumber_plugin:
The method getRegionInfoFromPhoneNumber "discovers" what country the number is from eg +55... it would interpret as it's from Brasil and proceed to format the phone number accordingly. You can also explicitly tell from where the phone number is from passing the country's acronym into the method eg. await PhoneNumber.getRegionInfoFromPhoneNumber(phone, "US"); It'll disregard a country code if it doesn't fit the number you're entering.
String phone = "+19795555555";
PhoneNumber number =
await PhoneNumber.getRegionInfoFromPhoneNumber(phone);
String formattedNumber = await PhoneNumberUtil.formatAsYouType(
number.phoneNumber!,
number.isoCode!,
);
print(formattedNumber); // -> prints: '+1 979-555-5555'
Also you can use: https://pub.dev/packages/intl_phone_number_input/example
String phoneNumber = '+234 500 500 5005';
PhoneNumber number = await PhoneNumber.getRegionInfoFromPhoneNumber(phoneNumber);
String parsableNumber = number.parseNumber();
`controller reference`.text = parsableNumber

type 'String' is not a subtype of type 'ImageProvider<dynamic>'

I have list of categories and tapping on each of them shows users of that category in new screen. The new screen has an image widget and text widget. I am getting this error if a user has a profile picture, and if there's no profile picture associated with that user, a default picture is shown which doesn't throw this error.
Widget _getProfilePic(Pro pro) {
// If the pro has provided a profile picture
if(pro.profilePhoto.length > 0) {
// If the pro is available for a video call
if(statusMap[pro.onlineStatus] == "Online, available") {
return CircleAvatar(
radius: 30.0,
backgroundImage: pro.profilePhoto.startsWith("./profilepics") ? NetworkImage("" + pro.profilePhoto.substring(2)) : pro.profilePhoto);
}
// If pro is not available
else {
return CircleAvatar(
radius: 30.0,
backgroundImage: pro.profilePhoto.startsWith("./profilepics") ? NetworkImage("" + pro.profilePhoto.substring(2)) : pro.profilePhoto);
}
}
// Else, provide a default icon
else {
// If the pro is available for a video call
if(statusMap[pro.onlineStatus] == "Online, available") {
var profileImg = Image.asset('icons/default_profile_icon.png', height: 60.0);
return Image.asset('icons/default_profile_icon.png', height: 60.0);
}
// If the pro is not available
else {
return Image.asset('icons/default_profile_icon.png', height: 60.0);
}
}
This is the Pro class model:
class Pro extends User {
String company;
String experience;
double rating;
int reviewCount;
int onlineStatus;
String proId;
Pro();
// Returns a Pro created from JSON
factory Pro.fromJson(Map<String, dynamic> json) {
Pro pro = Pro();
pro.proId = json['ProID'] as String;
pro.fullname = json['FullName'] as String;
pro.company = json['Company'] as String;
pro.experience = json['about'] as String;
pro.rating = json['ReviewAvg'] != null? double.tryParse(json['ReviewAvg']) : 0.0;
pro.reviewCount = json['ReviewCount'];
pro.onlineStatus = json['OnlineStatus'];
pro.profilePhoto = json['profile_pic'] as String;
return pro;
}
}
// Converts a http response body into a List<Pro>
List<Pro> parsePros(String responseBody) {
final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Pro>((json) => Pro.fromJson(json)).toList();
}
You probably need to wrap pro.profileImage in NetworkImage in the two places you test for ./profilepics