I am making Flutter application that will display stories for kids. In the story text I am using there are certain words such as rustling, honking, etc. For example, "Mimi and Sami heard a honking sound", and I want my application to play corresponding sounds when these words are clicked. My question is that how can I control the behaviour of any word in String so that I am able to play relevant sounds when those buttons are clicked?
So far I have not been able to find any solution for this. My question is not about playing sound in general, but controlling behavior of any word in a String. I understant TextSpan might be of any help, but I guess it would be hectic to use it.
You can use the GestureRecognizer from import 'package:flutter/gestures.dart';
RichText(
text: TextSpan(
children: [
TextSpan(
text: 'Single tap',
recognizer: TapGestureRecognizer()..onTap = () {
// play music here
},
),
TextSpan(
text: ' Double tap',
recognizer: DoubleTapGestureRecognizer()..onDoubleTap = () {
// play music here
}
),
TextSpan(
text: 'Long press',
recognizer: LongPressGestureRecognizer()..onLongPress = () {
// Long Pressed.
},
),
],
),
)
How can I fix that? I can't run the code because there is an error at String
Text(
questions[_questionsIndex]['questionText'] as String,
style: TextStyle(color: Colors.orange, fontSize: 30),
),
...(questions[_questionsIndex]['questionText'] as List<String>).map((answer) {
return Answer(_answerQuestions, answer);
}).toList()
The problem is this:
questions[_questionsIndex]['questionText'] as String
questions[_questionsIndex]['questionText'] as List<String>
How can questions[_questionsIndex]['questionText'] be a String and a List<String> at the same time?
I can't know for sure since you didn't show whats inside of questions variable and we don't know what you want to do but you probably want to do something like this:
...(questions as List<Map<String, dynamic>>).map((question) {
return Answer(_answerQuestions, question['questionText']);
}).toList()
I decided to do an online course at Udemy (flutter) and this code was shown, to load the questions & answers by a quiz:
Question(
questions[_questionsIndex]['questionText'],
),
...(questions[_questionsIndex]['questionText'] as List<String>).map((answer) {
return Answer(_answerQuestions, answer);
}).toList()
but actually it doesn't work. I tried to put 'as String' to the first Line, but the Emulator does show an error. So I tried your Version but it doesn't helped me
It seems that whenever I focus on a TextField (that sits inside a SliverPersistentHeader) SliverList+SliverPersistentHeader scrolls down. I have created some mockups of what I mean below:
So in this mockup, the user starts off at the first layout, scrolls up to continue viewing the lsit and then when they click on the TextField, the whole thing shifts down. Any way to stop that?
I have also attached my basic Scaffold code for your perusal:
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Consts.coMainBackground,
resizeToAvoidBottomInset: false,
body: CustomScrollView(
slivers: <Widget>[
_sliverAppBar(),
_makeHeader(),
BlocBuilder<AllPersonsBloc, AllPersonsState>(
builder: (context, state) {
if (state is AllPersonsLoading) {
return _buildLoading();
} else if (state is AllPersonsLoaded) {
return _sliverList(context, state.persons);
} else if (state is AllPersonsError) {
return _buildErrorMessage(state.message);
} else {
return _buildErrorMessage('Unknown error!');
}
},
),
],
),
);
}
the _makeHeader creates the SliverPersistentHeader and the rest I think should make sense based on names.
Your help would greatly appreciated :)
Thanks!
Got it...
return SliverAppBar(
automaticallyImplyLeading: false,
backgroundColor: Consts.coForestGreenBackground,
expandedHeight: 207,
titleSpacing: 0,
elevation: 0,
floating: false,
pinned: false,
snap: false,
flexibleSpace: FlexibleSpaceBar(
Note that the item is not pinned/floated/snapped. Then its important that the input (TextField in this case) has a scrollPadding (top) of 0.
Your scaffold will ALSO need an appbar. So technically you have an appbar and a SliverAppBar but the SliverAppBar is just to wrap the flexibleSpace.
Or rather, zero after any padding on the element it self. In my case its 40 since the TextField has a top padding of 30 and another 10 from the element that contains it etc.
I'm trying to create a system in which I can validate a string to check if it's a url or not. (https://www.google.com/)
I found the flutter package validator but this isn't dart 2 compatible, so won't be compatible with my code.
Similarly named, I also found the validators package but I can't seem to get it working correctly with my code, as it throws the following error; (hope you like my project name ;)
Because every version of flutter_test from sdk depends on test 1.3.0
and every version of validators depends on test ^1.3.3, flutter_test from sdk is incompatible with validators.
So, because gucci depends on both validators ^1.0.0+1 and flutter_test any from sdk, version solving failed.
Unable to reload your application because "flutter packages get" failed to update package dependencies.
Exception: pub get failed (1)
If you could either find a fix for validators so that it doesn't throw this error and thus works correctly with my code, or suggest another method of validating a string to be URL compliant that would be great.
Thanks
Edit - My pubspec.yaml file
name: gucci
description: A new Flutter project.
dependencies:
flutter:
sdk: flutter
cupertino_icons:
barcode_scan:
gradient_app_bar:
url_launcher:
validate: ^1.7.0
dev_dependencies:
flutter_test:
sdk: flutter
fonts:
- family: PlayfairDisplay
fonts:
- asset: fonts/PlayfairDisplay-BoldItalic.ttf
- family: Kanit
fonts:
- asset: fonts/Kanit-ExtraBoldItalic.ttf
- family: Poppins
fonts:
- asset: fonts/Poppins-BoldItalic.ttf
- family: PoppinsLightItalic
fonts:
- asset: fonts/Poppins-LightItalic.ttf
- family: PoppinsMediumItalic
fonts:
- asset: fonts/Poppins-MediumItalic.ttf
To check Valid URL string you just have to use Uri.parse() like below.
bool _validURL = Uri.parse(_adVertData.webLink).isAbsolute;
Just check value of _validURL
Uri.tryParse(mystring)?.hasAbsolutePath ?? false;
Some example results:
url
result
'https://stackoverflow.com/questions/52975739/dart-flutter-validating-a-string-for-url'
true
asd
false
asd:asd
false
%EMPTY_STRING%
false
google.nl
false
https:
false
https://
false
https://a
false
https://a/
true
var urlPattern = r"(https?|http)://([-A-Z0-9.]+)(/[-A-Z0-9+&##/%=~_|!:,.;]*)?(\?[A-Z0-9+&##/%=~_|!:,.;]*)?";
var match = new RegExp(urlPattern, caseSensitive: false).firstMatch('https://www.google.com');
You can use RegExp too.
I used the following method below. Depending on your rec, all valid URLs need to have a host (ex, google.com). If a URL does not have a host it returns an empty string (not undefined or null).
bool isURLValid = Uri.parse('https://google.com/').host.isNotEmpty;
Using .isAbsolute, as some have already reported, marks URLs such as 'http:' to be valid URLs which not.
For some reason, the validators package is requiring a pretty recent version of flutter's testing library rather than leaving it up to the application. Maybe there's a good reason for that (i.e. they're using a new feature).
The flutter engine internally requires a particular version of the flutter_test library (which is why it's generally a bad idea to specify a version of it). So to fix this you'll have to upgrade your flutter by running flutter upgrade. If you're already at the most recent version of the channel you're in, you may have to run flutter channel dev or flutter channel master to switch to a channel (branch really) that's updated more often.
I run on the dev branch/channel for the most part and while it very occasionally has problems, it doesn't happen a lot. I'd advise against using the master branch if possible though.
Validation using RegEx
String hasValidUrl(String value) {
String pattern = r'(http|https)://[\w-]+(\.[\w-]+)+([\w.,#?^=%&:/~+#-]*[\w#?^=%&/~+#-])?';
RegExp regExp = new RegExp(pattern);
if (value.length == 0) {
return 'Please enter url';
}
else if (!regExp.hasMatch(value)) {
return 'Please enter valid url';
}
return null;
}
Validation using in-built package
final Uri uri = Uri.tryParse(value);
if (!uri.hasAbsolutePath) {
return 'Please enter valid url';
}
If you want some special case like you have to validate deepLink then RegEx practice is best.
For RegExp, if you are going to find URL in a string, you can use this one.
r'^((?:.|\n)*?)((http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)([-A-Z0-9.]+)(/[-A-Z0-9+&##/%=~_|!:,.;]*)?(\?[A-Z0-9+&##/%=~_|!:,.;]*)?)'
It can be used when you are highlighting URL in a string. For example in a chat app, you can highlight URL in a sent chat message.
This validates google.com, https://google.com, http://google.com all.
I'm using this way to validate Urls. In your TextFormField's use this validator. here your url should be start from www.
validator: (website) {
String pattern =
r'^((?:.|\n)*?)((http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)([-A-Z0-9.]+)(/[-A-Z0-9+&##/%=~_|!:,.;]*)?(\?[A-Z0-9+&##/%=~_|!:,.;]*)?)';
RegExp regExp = RegExp(pattern);
if (website.isEmpty) {
return "Please enter your website";
} else if (!(regExp.hasMatch(website))) {
return "Website Url must be started from www";
} else {
return null;
}
},
TextEditingController urlController = TextEditingController();
String urlData = '';
static final GlobalKey<FormFieldState<String>> _orderFromkey =
GlobalKey<FormFieldState<String>>();
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
resizeToAvoidBottomInset: false,
body: Column(
children: [
appBar(label: appName),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
key: _orderFromkey,
controller: urlController,
validator: (value) {
String patttern = r"((https?:www\.)|(https?:\/\/)|(www\.))[-a-zA-Z0-9#:%._\+~#=]{1,256}\.[a-zA-Z0-9]{1,6}(\/[-a-zA-Z0-9()#:%_\+.~#?&\/=]*)?";
RegExp regExp = new RegExp(patttern);
if (!regExp.hasMatch(value!)) {
return 'Please enter valid URL';
}
},
decoration: InputDecoration(
fillColor: appColor,
labelText: "url",
labelStyle: new TextStyle(color: appColor),
contentPadding: EdgeInsets.only(left: 10, right: 10),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: appColor),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: black),
),
hintText: 'Enter Your URL'),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: InkWell(
onTap: () {
print('_orderFromkey: ${_orderFromkey}');
final FormFieldState<String>? form =
_orderFromkey.currentState;
if (form!.validate()) {
urlData = urlController.text;
Get.toNamed('/showQr', arguments: urlData);
print('text : ${urlData}');
} else {
// _autoValidation = true;
}
},
child: Container(
width: ScreenSize.size.width * 0.6,
height: ScreenSize.size.height * 0.1,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: appColor,
),
child: const Align(
alignment: Alignment.center,
child: Text(
'Submit',
style: TextStyle(
fontSize: 20,
color: white,
fontWeight: FontWeight.w700),
textAlign: TextAlign.center,
)),
),
),
),
],
)),
);
}
You can use the url_launcher package for this.
Future<bool> checkIfUrlIsValid({required String url}) async {
if (await canLaunchUrl(Uri.parse(url))) {
return true;
}
return false;}
checkIfUrlIsValid(url: 'https://google.com'); // true;
checkIfUrlIsValid(url: 'google com'); // false;
Use this simple function then you can identify string is valid URL or not
bool isURl(String url){
return RegExp(r'^((?:.|\n)*?)((http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)([-A-Z0-9.]+)(/[-A-Z0-9+&##/%=~_|!:,.;]*)?(\?[A-Z0-9+&##/%=~_|!:,.;]*)?)')
.hasMatch(url); }
I need some help, I've been figuring this for almost an hour and still can't find a way to fix this.
I have a search form to filter data from my CGridView, and I also need a button to view all the records after I finish using search, but I can't figure how to do it. Here's my code for jquery refresh button:
Yii::app()->clientScript->registerScript('initRefresh',<<<JS
$('#refresh-button').on('click',function() {
$('#app-asset-categories-grid').yiiGridView('update');
return false;
});
JS
,CClientScript::POS_READY);
Here's my code for jquery search form:
Yii::app()->clientScript->registerScript('search', "
$('.search-button').click(function(){
$('.search-form').toggle();
return false;
});
$('.search-form form').submit(function(){
$('#app-asset-categories-grid').yiiGridView('update', {
data: $(this).serialize()
});
return false;
});
");
And finally, my grid:
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataProvider,
'id'=>'app-asset-categories-grid',
'columns' => array(
'category_id',
'label',
'description',
'add_date',
'modification_date',
array(
'name'=>'Status',
'filter'=>array('1'=>'Active', '0'=>'Inactive'),
'value'=>'($data->status=="1")?"Active":"Inactive"'
),
array(
'name'=>'Deletion Status',
'filter'=>array('1'=>'Deactivate','0'=>'Active'),
'value'=>'($data->deletion_status=="1")?"Deactivated":"Activated"'
),
array(
'class'=>'CButtonColumn',
),
),
));
I just wanted a refresh button to display all the data again after I use my search form. I need your help guys, thanks.
You need to handle update action in model and set pagination parameter false. An example how to do it:
Add hidden field in search form _search.php
<?php echo CHtml::hiddenField('show_all', 0, array("id"=>"show_all")); ?>
Then handle it in model's search() function (your grid uses it to get data)
like this:
$criteria=new CDbCriteria;
// some criterias
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
'pagination' => (isset($_GET["show_all"]) && $_GET["show_all"])?false:array(), // add this line
));
Then set update hidden field when you need it.
$('#refresh-button').on('click',function() {
$('#show_all').val(1); // set it to show all
$('#app-asset-categories-grid').yiiGridView('update');
$('#show_all').val(0); // set to 0 for searching with pagination
return false;
});
Thats it.