How to hide elements in webview in Flutter.? [duplicate] - flutter

I'm beginner to flutter , I want to hide section of website in my flutter application . I added flutter flutter_webview_plugin in pubspec.yaml file and imported package to my feed.dart page. the flutterWebviewPlugin.evalJavascript("alert('Hi, I just executed')"); is executed when i run the application. But flutterWebviewPlugin.evalJavascript("document.getElementById('header04-2j').style.display = 'none';"); i tried to hide header but its not working.
Bellow is the source code .. Please help .
enter code here
import 'package:flutter/material.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
class FeedPage extends StatefulWidget {
#override
FeedPageState createState() {
return new FeedPageState();
}
}
class FeedPageState extends State<FeedPage> {
final flutterWebviewPlugin = new FlutterWebviewPlugin();
// alternatively you can define variable as var js = "YOUR_SCRIPT"; and use it inside evalJavascript
#override
void initState(){
super.initState();
flutterWebviewPlugin.evalJavascript("alert('Hi, I just executed')"); // executed
flutterWebviewPlugin.evalJavascript("document.getElementById('header04-2j').style.display = 'none';"); // not executed
}
#override
void dispose() {
flutterWebviewPlugin.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return WebviewScaffold(
url: 'https://www.esdatech.com/',
hidden: true,
appBar: AppBar(title: Text("ESDA")),
);
}
}
enter image description here

This is likely due to your webpage not being loaded, and therefore the element not existing, at the point you call that method in your code.
A solution would be to wait until the page is loaded before attempting to remove the element using the onStateChanged stream.
StreamSubscription<WebViewStateChanged> _onStateChanged;
#override
void initState(){
super.initState();
flutterWebviewPlugin.evalJavascript("alert('Hi, I just executed')");
_onStateChanged =
flutterWebViewPlugin.onStateChanged.listen((WebViewStateChanged state) {
if(state.type == WebViewState.finishLoad) {
flutterWebviewPlugin.evalJavascript("document.getElementById('header04-2j').style.display = 'none';");
}
}
);
}
#override
void dispose() {
_onStateChanged.cancel();
flutterWebviewPlugin.dispose();
super.dispose();
}

Related

Flutter WorkManager Background Fetch Example With StateFull Widget

I have a function called control in the StateFull Widget. I want to run this function with WorkManager every 15 minutes.
How can I call the control function from the callbackDispatcher function?
I added a Stream statically to the Statefull widget and then listened to it but it didn't work.
HomeScreen.dart file
import 'package:flutter/material.dart';
import 'package:workmanager/workmanager.dart';
const taskKontrol = "control";
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
#override
Widget build(BuildContext context) {
return Container();
}
#override
void initState() {
super.initState();
setupWorkManager();
}
void control() async
{
//... my code control is here
}
}
void setupWorkManager() async {
await Workmanager.initialize(callbackDispatcher, isInDebugMode: true);
Workmanager.registerPeriodicTask(taskKontrol, taskKontrol,
frequency: Duration(seconds: 10),
existingWorkPolicy: ExistingWorkPolicy.append
);
}
void callbackDispatcher() {
Workmanager.executeTask((taskName, inputData) async {
switch(taskName)
{
case taskKontrol:
// How can I call the control function from here?
print("control from workmanager");
break;
}
return Future.value(true);
});
}
For those who still looking for an answer:
From the official docs:
The callbackDispatcher needs to be either a static function or a top level function to be accessible as a Flutter entry point.
I had this same problem and I solved it by moving the function callbackDispatcher to the file: main.dart
Also, the code that initializes callbackDispatcher must be in main() before the App() widget loads.
To call your control code, create a class with static function control()
Note: You cannot call the widget's method from callbackDispatcher!
Reason: Widgets are UI bound. As long as the screen remains active, the widget that is visible remains active. Once you close the app or move on to next screen, the widgets' memory gets recycled. But this callbackDispatcher gets executed even when your app is closed. So, it has to be isolated from UI code.
Here's the code:
main.dart:
import 'package:flutter/material.dart';
import 'package:workmanager/workmanager.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Workmanager().initialize(callbackDispatcher, isInDebugMode: true);
runApp(App());
}
void callbackDispatcher() {
Workmanager.executeTask((taskName, inputData) async {
switch(taskName)
{
case ScheduledTask.taskName:
ScheduledTask.control(); // calls your control code
break;
}
return Future.value(true);
});
}
class ScheduledTask {
const static String taskName = "control";
static void control() {
// add your control here
}
}
All you can do from HomeScreen widget is to call setupWorkManager() that schedules the task
class _HomeScreenState extends State<HomeScreen> {
#override
Widget build(BuildContext context) {
return Container();
}
#override
void initState() {
super.initState();
setupWorkManager();
}
}
void setupWorkManager() async {
Workmanager.registerPeriodicTask(taskKontrol, taskKontrol,
frequency: Duration(minutes: 15),
existingWorkPolicy: ExistingWorkPolicy.append
);
}
Note: The minimum frequency for the recurring task is 15 minutes

How to use didChangeAppLifecycleState with Flutter Hooks

I am using Flutter with hooks and I am trying to get the App Life Cycle State. I followed documentation and created new hook (code shown below) which works ok for all situations with one exception. When the application state becomes "paused", the hook does not return the value back to the widget. I am not clear what to do at this point. Someone suggested using Isolates but I don't see how that can help. Updating App Life Cycle is not compute expensive.
Please let me know what else I could do make this work.
Thanks
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
AppLifecycleState useAppLifecycleState() {
return use(const _LifeCycleState());
}
class _LifeCycleState extends Hook<AppLifecycleState> {
const _LifeCycleState();
#override
__LifeCycleState createState() => __LifeCycleState();
}
class __LifeCycleState extends HookState<AppLifecycleState, _LifeCycleState>
with WidgetsBindingObserver {
AppLifecycleState _state;
#override
void initHook() {
super.initHook();
WidgetsBinding.instance.addObserver(this);
}
#override
void dispose() {
super.dispose();
WidgetsBinding.instance.removeObserver(this);
}
#override
AppLifecycleState build(BuildContext context) {
return _state;
}
#override
void didChangeAppLifecycleState(AppLifecycleState state) {
setState(() {
_state = state;
});
super.didChangeAppLifecycleState(state);
}
}
Thanks for your help.

Get HTML element with web scraping on flutter

i´m trying to get the link of the video of this page with the package "web_scraper". I can find it using Chrome´s tools (is an attribute of a jw-video jw-reset element. The problem is that when you enter the page you can´t see this attribute before clicking in the play button. Can any one help me?
I have already this code:
import 'package:flutter/material.dart';
import 'package:web_scraper/web_scraper.dart';
class Prueba extends StatefulWidget {
#override
State createState() => new _Prueba();
}
class _Prueba extends State<Prueba> {
final webScraper = WebScraper('https://www3.animeflv.net');
List<Map<String, dynamic>> link;
void fetchProducts() async {
// Loads web page and downloads into local state of library
if (await webScraper
.loadWebPage('/ver/sword-art-online-alicization-war-of-underworld-20')) {
setState(() {
link = webScraper.getElement(
'div.jw-wrapper.jw-reset > div.jw-media.jw-reset > video.jw-video.jw-reset', ['src']);
});
}
}
#override
void initState() {
super.initState();
// Requesting to fetch before UI drawing starts
fetchProducts();
}
#override
Widget build (BuildContext ctxt) {
print(link);
return Container();
}
}

What is the equivalent of Android LiveData in Flutter?

Android's LiveData allows to update the UI when the activity is in an active state. So if a background operation has finished while the activity is paused, the activity won't be notified and thus the app won't crush. Can Flutter perform the same behavior?
For people interested in an equivalent of LiveData for other scenarios, I present you StreamController:
class ExampleViewModel {
StreamController<bool> loggedInStream = StreamController<bool>();
logIn() { loggedInStream.add(true); }
}
class ExampleScreen extends StatefulWidget {
#override
State<StatefulWidget> createState() => ExampleScreenState();
}
class ExampleScreenState extends State<ExampleScreen> {
ExampleViewModel _viewModel;
BuildContext _ctx;
#override
void initState() {
super.initState();
_viewModel = ExampleViewModel()
_viewModel.loggedInStream.stream.listen( (loggedIn) {
if ( loggedIn != null && loggedIn ) {
Navigator.of(_ctx).pushReplacementNamed("/home");
}
});
}
#override
Widget build(BuildContext context) {
_ctx = context;
var loginBtn =
RaisedButton(
onPressed: _viewModel.logIn(true),
child: Text(
"LOGIN",
style: new TextStyle(
fontSize: 24.0,
)
),
color: Colors.green,
textColor: Colors.white,
);
return loginBtn;
}
#override
void dispose() {
super.dispose();
_viewModel.loggedInStream.close();
}
}
You can subscribe to it just like a LiveData, using:
loggedInStream.stream.listen( (data) { code } )
And you should clear the listeners in dispose to avoid memory leaks:
loggedInStream.close()
This code basically do the following things:
Creates a screen with a button.
Listen to a Stream (observe a LiveData).
When you click the button, it changes the value.
The listener (observer) is triggered.
Launches new screen.
You can use WidgetsBindingObserver to listen to the application state.
class AppLifecycleReactor extends StatefulWidget {
const AppLifecycleReactor({ Key key }) : super(key: key);
#override
_AppLifecycleReactorState createState() => new _AppLifecycleReactorState();
}
class _AppLifecycleReactorState extends State<AppLifecycleReactor> with WidgetsBindingObserver {
#override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
#override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
AppLifecycleState _notification;
#override
void didChangeAppLifecycleState(AppLifecycleState state) {
setState(() { _notification = state; });
}
#override
Widget build(BuildContext context) {
return new Text('Last notification: $_notification');
}
}
Easy: Flutterx Live Data
There is no need to observe App lifecycle: widget are built only when the app is resumend
This library integrates perfectly LiveData concepts, also is well documented.
Is developed on Flutter 1.14.x-dev you need master flutter channel at the moment
Sorry to be late for the party,
My colleague and I have developed a library that mimics the live data of android, on flutter.
Check it out:
https://pub.dev/packages/stream_live_data

What is the equivalent code in flutter for " mAdapter.notifyDataSetChanged();";

Befor HTTP response show loading and after https response create tab view. I successfully create tab view but my problem is after HTTP request unable to update the view in the android studio with java we use
`mAdapter.notifyDataSetChanged();
mActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
}
});`
code for doing this.
what is the equivalent code in the flutter?
If you want update any widget in flutter you should call setState((){})
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool isLoading = false;
#override
void initState() {
super.initState();
isLoading = true;
getData();
}
#override
Widget build(BuildContext context) {
return isLoading ? new CircularProgressIndicator() : // show list;
}
Future<ModelClass> getData() async {
// get data from http
...
// after processing response
setState(() {
isLoading = false;
});
}
}
In Flutter, the UI is updated when the State is changed using setState method.
In your case, you will need some variables (E.x: isLoading, items (for your list)).
When the app loads data from backend, isLoading = true, items = [] (empty). When the request is done, isLoading = false and items = [item1, item2,...]. Here is where you have to use setState method to update your UI.
Under your build method, you have to use these 2 variables to render the corresponding UI.