This may be a duplicate question as I have seen a lot of questions that has to do with iframes, webview and all that but each one gets me more confused as I study them. Currently I am making use of the WebView widget to display a webview in my mobile app. I wish to build for the web now but WebView is not supported for web so I have been seeking for an alternative approach. I got to know about HtmlElementView from the flutter documentation. Trying to research into it but I can not seem to find any clear way I am supposed to use it to solve my problem.
Here is my code:
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
margin: EdgeInsets.fromLTRB(0, 15, 0, 0),
child: !kIsWeb
? WebView(
initialUrl: this.widget._url,
javascriptMode: JavascriptMode.unrestricted,
onPageStarted: this._pageStarted,
)
: HtmlElementView(
viewType: '',
),
),
),
);
}
From my code, I am building the WebView when not compiled for web and building HtmlElementView when compiled for web. As much as I hate to say it, this is as far as my knowledge can go for now on HtmlElementView. From the docs, viewType is to take a String which I do not really know anything about.
What I wish to do exactly? The contents loaded in WebView is kind of dynamic so I wish to load same in the HtmlElementView. Any help or maybe materials that could help me in this would be so much appreciated as I am new to all these. Thanks.
I'm currently on the same quest and found this handy, simple example:
https://codepen.io/riccio85/pen/wvMeaMe
import 'dart:html';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
void main() {
// ignore: undefined_prefixed_name
ui.platformViewRegistry.registerViewFactory(
'hello-html',
(int viewId) => IFrameElement()
..width = '500'
..height = '360'
..src = 'https://www.youtube.com/embed/xg4S67ZvsRs'
..style.border = 'none');
runApp( Padding(
padding: EdgeInsets.all(25),
child: SizedBox(
width: 640,
height: 360,
child: HtmlElementView(viewType: 'hello-html'),
),
),
);
}
It's not perfect but it seems to do what I need to. Which is to say, I also end up checking for web in the same way as your example and use webview_flutter otherwise.
Seems to be a bit of a shortcoming with the whole thing at the moment, let's hope the situation improves.
Related
I have recently started learning flutter and got stuck at my very first basic hello world application:/
So, basically I am trying to center the entire content on the screen using the center tag, but it is not working, it would be really helpful if someone looks into my problem and helps me:)
Here's the code
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: Center(child: Text('Hello World'))));
}
The application screen:
Try this:
void main() {
runApp(MaterialApp(
home: Scaffold(
body: Center(
child: Text('Hello World')
),
),
),
);
}
Text needs an ancestor of Material to be rendered "correctly" and since Scaffold has one, it'll work fine.
I followed this tutorial which explores creating a ui for a movie app
https://www.youtube.com/watch?v=OgSLd2lH1FM&feature=youtu.be
While most of the design I was able to recreate and add my own settings to,I face a problem in the Poster display side of the tutorial, Mainly that in the builder, It is specified that the pages to the right and left of the one in focus are inclined at 15 degrees.:
The poster view should look like this
The transform.rotate part works, but only after the user starts scrolling horizontally in the poster list.
before the scroll it looks like this:
What the carousel looks like before scrolling
This happens both in the simulator and a real device. Also I tried using transform.translate to see if that gives the same problem but it does not.
Below is a code snippet of the Animated builder.
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
padding: const EdgeInsets.symmetric(
vertical: kDefaultPadding / 2, horizontal: 0),
child: AspectRatio(
aspectRatio: 0.85,
child: PageView.builder(
itemCount: movies.length,
controller: _pageController // declared PageController type in class//,
onPageChanged: (value) {
setState(() {
// initialPage was initialised with value 1
initialPage = value;
});
},
itemBuilder: (context, index) => buildMovieCard(index),
),
),
);
}
The animatedBuilder calling function is below.
Widget buildMovieCard(int index) => AnimatedBuilder(
animation: _pageController,
builder: (context, child) {
double value = 0;
if (_pageController.position.haveDimensions) {
value = index - _pageController.page;
//0.038 since it time pi gives 7 so 7 rotaitons
value = (value * 0.038).clamp(-1, 1);
}
return Transform.rotate(
child: MovieCard(movie: movies[index]),
angle: math.pi * value,
);
});
(Sorry if the information above is Convoluted.. )
Do tell me if there are any errors in the way I have framed this question
EDIT: I tried searching a bit more, and found a similar question.
it seems that animations won't be executed until an animation plays for an animated builder.
I dont have too much experience in animated builder stuff so if I find something ill add it
Here is the link to the question
I Tried using a SingleTickerProvider and an animation controller with .repeat() to continuously run the animatedBuilder. The rotation now does appear automatically, but it takes some time.
Is your _pageController.page set correctly at the start?
What happens if you print value inside your if:
if (_pageController.position.haveDimensions) {
...
print(value);
}
(sorry I don't have the reputation to comment directly on the question on this account)
I did not quite understand the code, but according to the description you might try to simulate a scroll or see what exactly the scroll affects, and try to implement it.
Hope I helped.
I have a MultiBlocProvider assigned for an app that has a Bottom Navigation Bar to navigate through main routes like Home, Search, Wishlist ...
I use setState(){} to change the currentPage for each route.
Recently I've added Blocs to each of them by using flutter_bloc package and I'm using BlocProvider to provide the bloc to each BlocBuilder,
#override
Widget build(BuildContext context) {
return SafeArea(
top: false,
child: Scaffold(
key: _scaffoldKey,
body: PageStorage(
child: Stack(
children: <Widget>[
AnimatedSwitcher(
duration: Duration(milliseconds: 200),
child: BlocProvider<WishlistBloc>(
create: (BuildContext context) => WishlistBloc(WishlistRepository()),
child: currentPage),
),
bottomBar(currentPageScroll)
],
),
bucket: bucket,
),
),
);
}
Is it ok to use MultiBlocProvider to provide all the BlocsProviders I need?
they could be more than 10 providers, would it affect the performance of the app?
It's definitely OK, MultiBlocProvider created for this purposes. But you need to understand, that if you with your creation also send(for e.x.) initialize event which started loading in all 10 blocs some data you will have some issues. So, if you will have some performance issues, please create separate SO question and community will help to find root-cause of this.
I'm developing WebView mobile application in Flutter and I would like to customize webview errors, because if customer will have his wifi turned off and he got "net::ERR_ADDRESS_UNREACHABLE", it's not so good. So i would like to change this page to some custom design and show something like "This application requires internet connection, you should turn your wifi on"..
Is something like this possible? I was searching in docs and found nothing.
Thanks a lot.
Not sure if we can modify the actual message shown from the webview itself, but there is a workaround that I have used.
You can use a Stack widget and show a custom message in a separate widget whenever the error occurs. A sample code is below.
Stack(
children: [
if (!controller.isError)
WebView(
javascriptMode: JavascriptMode.unrestricted,
initialUrl: "https://some-random-url.com",
onPageFinished: controller.onLoaded,
onWebResourceError: controller.onError,
),
if (controller.isLoading)
Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.black),
),
),
if (controller.isError)
Center(
child: Padding(
padding: const EdgeInsets.only(left: 8.0, right: 8.0),
child: Text(
text: "Something went wrong, please try again",
),
),
)
],
),
The Controller object you see is a GetX controller which I use for state management, you are free to use whatever you like. The main action elements are
isError -> State variable which monitors if an error has occurred.
WebView.onWebResourceError -> Callback function called when a certain error occurs.
You can pass a function to this and this callback is only called when an error occurs. With this, you can then modify the state variable isError to be true, which will, in turn, hide the webview and show an error message at the center of the screen.
With this, you will have the error handling you are looking for.
PS: I know I am late for this answer, but I hope somebody else finds it useful.
I'm learning mobile dev using flutter, with little programming background. Just want to know which is a better practice and does it affect performance of the code. Let say I have 5 RaisedButton
Should I do like this. Or make a different file and access the constructor of the new class? The only difference is the text on the button and the route
children: <Widget>[
RaisedButton(
elevation: 0.1,
child: Text('Attandence Tag'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => UserTag()),
);
},
),
RaisedButton(
elevation: 0.1,
child: Text('Add New Student'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => CreateUser()),
);
},
),
thanks for answering
If you have special styling it's definitely worth to define it in an other file.
If you want to change the style you just have one widget to change it's easier and it simplify your code.
But (because nothing is perfect), Flutter produce easily spaghetti code, so it's up to you to make it clear the way you want. The best way is the one you feel comfortable with, and you have to try things to discover it.