- Edited
Flutter üzerinden webview nasıl kullanılır,
Flutter’da webview javascript nasıl aktif edilir, tasarım olarak nasıl gözüküyor, IOS webview uygulama onaylıyor mu inceleyeceğiz.
İzleyemeden anlayamam diyenler için : YouTube linki
Flutter üzerinden webview nasıl kullanılır,
Flutter’da webview javascript nasıl aktif edilir, tasarım olarak nasıl gözüküyor, IOS webview uygulama onaylıyor mu inceleyeceğiz.
İzleyemeden anlayamam diyenler için : YouTube linki
Bazı developerlar gerek uğraşmak istemediği için gerekse farklı nedenlerden dolayı websitesinin mobil uygulamasını başta kodlamak yerine mobil uyumlu websitesini bir app’e gömer ve yayına alır.
Etik veya değil bunu tartışmak yerine gelin mantığına ve nasıl olduğuna bakalım.
# Yeni proje oluştur
$ flutter create my_webview_project
# proje dizinine gir ve vs Code ile aç
$ cd my_webview_project && code .
dependencies:
flutter:
sdk: flutter
webview_flutter: ^0.3.14+1
IOS için Info.plist dosyasına gömülü görünümlerin önizlemesinin gelmesi için , uygun değerleri eklememiz gerekir
<key>io.flutter.embedded_views_preview</key>
<true/>
Android için ekstra bir ayar istemeye gerek yok (internete erişim iznini aldığınızı varsayıyorum)
main.dart
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() => runApp(MaterialApp(home: WebViewExample()));
class WebViewExample extends StatefulWidget {
@override
_WebViewExampleState createState() => _WebViewExampleState();
}
WebViewController controllerGlobal;
Future<bool> _exitApp(BuildContext context) async {
if (await controllerGlobal.canGoBack()) {
print("onwill goback");
controllerGlobal.goBack();
} else {
Scaffold.of(context).showSnackBar(
const SnackBar(content: Text("No back history item")),
);
return Future.value(false);
}
}
class _WebViewExampleState extends State<WebViewExample> {
final Completer<WebViewController> _controller =
Completer<WebViewController>();
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () => _exitApp(context),
child: Scaffold(
appBar: AppBar(
// This drop down menu demonstrates that Flutter widgets can be shown over the web view.
actions: <Widget>[
NavigationControls(_controller.future),
],
),
body: Builder(builder: (BuildContext context) {
return WebView(
initialUrl: 'https://www.flutterforum.org/',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
onPageFinished: (String url) {
print('Page finished loading: $url');
},
);
}),
),
);
}
}
class NavigationControls extends StatelessWidget {
const NavigationControls(this._webViewControllerFuture)
: assert(_webViewControllerFuture != null);
final Future<WebViewController> _webViewControllerFuture;
@override
Widget build(BuildContext context) {
return FutureBuilder<WebViewController>(
future: _webViewControllerFuture,
builder:
(BuildContext context, AsyncSnapshot<WebViewController> snapshot) {
final WebViewController controller = snapshot.data;
controllerGlobal = controller;
return Text("");
},
);
}
}
Bu şekilde kolaylıkla bir webview uygulama oluşturabilrsiniz.
Apple, android gibi uygulama testi için algoritmik yapay zekalar değil gerçek kişiler tarafından testlerini sağlıyor. Durum böyleyken, webview uygulamayı olduğu gibi kabul ettirmek çok zor. Ama mümkünatı var elbette.
Yapmanız gereken webview yanında ekstra birşeyler eklemek. Yandan açılır menü, appbar, alt gezinme araçları, bildirim vs. Bu şekilde birkaç ekleme yaparsanız Apple’da kabul edecektir.
Ekstra merak ettiğiniz birşey varsa, bilgim dahilindeyse sorarsanız eklerim.
İyi çalışmalar.
Bu WebView eklentisinde bir türlü arka planda oynatmayı kapatamadım hocam. Home tuşuna basınca Android ekranına gelince yani video arka planda oynamaya devam ediyor. Kodlarım şu şekilde hocam:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class MyWebView extends StatelessWidget {
final String title;
final String selectedUrl;
final Completer<WebViewController> _controller =
Completer<WebViewController>();
MyWebView({
@required this.title,
@required this.selectedUrl,
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: WebView(
initialUrl: selectedUrl,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
));
}
}
AlperDuzgun Benim yazdığım kodları dener misiniz ?
Flutter selam hocam sizin yazdığınız kodlar ile
final String title;
final String selectedUrl;
kullanarak başka bir sınıftan veri gönderemedim. StatelessWidget da bunu yapabilirken, StatefullWidget da bunu yapamadım malesef.
başka bir sınıftan butona tıklanırken;
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => MyWebView(
title: “Google”,
selectedUrl: “https://google.com”,
)));
şeklinde url gönderebiliyorum, anca StatefullWidget da bunu yapamadım :/ Kusura bakmayın hem programlamada hem de Flutter da yeniyim
AlperDuzgun Başka sınıfta göndermek için o değişkenleri en üste yazıp diğer sayfada tanımlamanız yeterli.
Flutter Cevap verdiğiniz için ve ilgilendiğiniz için çok teşekkür ederim hocam Dediğim gibi yeni başladığım için kavramlar çok yabancı geliyor, örnekle gösterebilmeniz mümkün mü? Zaten size attığım örnekte en üstte yazılı ve dediğim gibi StatelessWidget da çalıştırabildim, ancak Statefull da çalışmıyor denedim :/ Çalışmıyordan kastım elbette bir yerde yanlış yapıyorum, sizin örneğiniz üzerinden gösterebilirseniz çok memnun olurum
AlperDuzgun final String title;
Burada statelessin içinde değil dışında dener misiniz ?
Ne yapmak istediğinizi yazın hocam
Ben size kod haline getirip atayım
Daha başlardayken soğutmalım sizi bu işlerden
Çok teşekkür ederim hocam ilginiz için, amacım aslında kod halinde almak değilde, stateless ın içinde tanımladığım string ve constructor ları statefull için de nasıl yapabileceğimi öğrenmek.
Benim şuan uygulamamda iki adet route um var. Birinci Linkleri gönderen butonların bulunduğu ana sayfa, diğeri ise webview in bulunduğu ayrı bir route.
Ana sayfada ki bir butona tıkladığımda örnek aşağıdaki gibi bir aksiyon için olsun.
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => MyWebView(
selectedUrl: “https://google.com”,
)));
Yukarıda ki selected url’deki değeri webview in bulunduğu route daki initialUrl: selectedUrl, ye göndermek istiyorum. Bunu Stateless Widget ile yapabiliyorum. String ve Constructor tanımlayarak oluyor. Ama işin içine StatefullWidget girince bu tanımlar çalışmıyor hocam. Ya yanlış yere yerleştiriyorum ya da StatefullWidget da bu tanımlar kullanılmıyor Acemi olduğumdan tam bilmiyorum. Kısa ve öz olarak StatefullWidget larda Route lar arası String değer gönderirken farklı yöntemler mi kullanılıyor? Bu ya da başka yöntemler kullanılıyorsa da bana basit bir örnek ile gösterirseniz sevinirim
İleride belki başka arkadaşlarında işine yarar
İlgi ve alakanız için teşekkür ederim
AlperDuzgun Elinize Sağlık
Flutter Ne için hocam?
AlperDuzgun import ‘dart:async’;
import 'package:flutter/material.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
const kAndroidUserAgent =
'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Mobile Safari/537.36';
String selectedUrl = '';
// ignore: prefer_collection_literals
void main() => runApp(VideoWebview());
class VideoWebview extends StatefulWidget {
String adres;
VideoWebview({this.adres});
@override
State<StatefulWidget> createState() => MyAppState(adres: adres);
}
int _bottomNavIndex = 0;
class MyAppState extends State {
String adres;
MyAppState({
this.adres
});
@override
void initState() {
selectedUrl=adres;
super.initState();
}
final flutterWebViewPlugin = FlutterWebviewPlugin();
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: WebviewScaffold(
appBar: AppBar(
backgroundColor: Colors.blueAccent,
actions: <Widget>[
BottomAppBar(
color: Colors.blueAccent,
child: Row(
children: <Widget>[
IconButton(
icon: const Icon(Icons.autorenew),
onPressed: () {
flutterWebViewPlugin.reload();
},
),
],
),
),
],
),
url: selectedUrl,
withZoom: true,
withLocalStorage: true,
hidden: true,
initialChild: Container(
color: Color.fromRGBO(34, 211, 95, 100),
child: const Center(
child: CircularProgressIndicator(),
),
),
),
));
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
// Instance of WebView plugin
final flutterWebViewPlugin = FlutterWebviewPlugin();
// On destroy stream
StreamSubscription _onDestroy;
// On urlChanged stream
StreamSubscription<String> _onUrlChanged;
// On urlChanged stream
StreamSubscription<WebViewStateChanged> _onStateChanged;
StreamSubscription<WebViewHttpError> _onHttpError;
StreamSubscription<double> _onProgressChanged;
StreamSubscription<double> _onScrollYChanged;
StreamSubscription<double> _onScrollXChanged;
final _urlCtrl = TextEditingController(text: selectedUrl);
final _codeCtrl = TextEditingController(text: 'window.navigator.userAgent');
final _scaffoldKey = GlobalKey<ScaffoldState>();
final _history = [];
@override
void initState() {
super.initState();
flutterWebViewPlugin.close();
_urlCtrl.addListener(() {
selectedUrl = _urlCtrl.text;
});
// Add a listener to on destroy WebView, so you can make came actions.
// Add a listener to on url changed
_onUrlChanged = flutterWebViewPlugin.onUrlChanged.listen((String url) {
if (mounted) {
setState(() {
_history.add('onUrlChanged: $url');
});
}
});
_onProgressChanged =
flutterWebViewPlugin.onProgressChanged.listen((double progress) {
if (mounted) {
setState(() {
_history.add('onProgressChanged: $progress');
});
}
});
_onScrollYChanged =
flutterWebViewPlugin.onScrollYChanged.listen((double y) {
if (mounted) {
setState(() {
_history.add('Scroll in Y Direction: $y');
});
}
});
_onScrollXChanged =
flutterWebViewPlugin.onScrollXChanged.listen((double x) {
if (mounted) {
setState(() {
_history.add('Scroll in X Direction: $x');
});
}
});
_onStateChanged =
flutterWebViewPlugin.onStateChanged.listen((WebViewStateChanged state) {
if (mounted) {
setState(() {
_history.add('onStateChanged: ${state.type} ${state.url}');
});
}
});
_onHttpError =
flutterWebViewPlugin.onHttpError.listen((WebViewHttpError error) {
if (mounted) {
setState(() {
_history.add('onHttpError: ${error.code} ${error.url}');
});
}
});
}
@override
void dispose() {
// Every listener should be canceled, the same should be done with this stream.
_onDestroy.cancel();
_onUrlChanged.cancel();
_onStateChanged.cancel();
_onHttpError.cancel();
_onProgressChanged.cancel();
_onScrollXChanged.cancel();
_onScrollYChanged.cancel();
flutterWebViewPlugin.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return WebviewScaffold(
primary: true,
key: _scaffoldKey,
url: selectedUrl,
appBar: AppBar(
title: const Text('Widget WebView'),
),
withZoom: true,
withLocalStorage: true,
hidden: true,
initialChild: Container(
color: Colors.redAccent,
child: const Center(child: CircularProgressIndicator()),
),
bottomNavigationBar: BottomAppBar(
child: Row(
children: <Widget>[
IconButton(
icon: const Icon(Icons.arrow_back_ios),
onPressed: () {
flutterWebViewPlugin.goBack();
},
),
IconButton(
icon: const Icon(Icons.arrow_forward_ios),
onPressed: () {
flutterWebViewPlugin.goForward();
},
),
IconButton(
icon: const Icon(Icons.autorenew),
onPressed: () {
flutterWebViewPlugin.reload();
},
),
],
),
),
);
}
}
Kodumuz bu
Çağırmak içinse
RaisedButton(
child: Text("Video Alternatif link"),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => VideoWebview(
adres: "https://www.youtube.com/",
)));
},
)
Selam hocam ellerinize sağlık, tam istediğim gibi çalıştı Ancak öğrenmek için kodlarınızı incelediğimde;
Statefull class ının içinde belirlediğiniz değişken ve constructor ları ile State class ının içinde de kullanmışsınız, orasını yapmamıştım :/ Eksiğimi orada görmüş oldum. Ancak aşağıdaki resimde belirttiğim 2 ve 4 numaranın neden kullanıldığını anlamadım
AlperDuzgun Bunlar en başta gönderdiğiniz url adresini widgetlera göndermek için
Flarum veya discourse için de uygulanabilir mi bu?
fakruzaruret evet
Flutter aynı bu yöntemi deneyeceğiz farklı bir şey yapmadan öyle mi?
fakruzaruret evet
Ben daha önce denediydim