使用 bottom navy bar flutter 来导航页面
Using bottom navy bar flutter to navigate pages
我正在使用这个 package 通过底部导航栏进行导航,我不明白如何设法在我的屏幕之间导航。如何通过底部导航栏图标在我的屏幕之间导航?
import 'dart:async';
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:bottom_navy_bar/bottom_navy_bar.dart';
class HaberScreen extends StatefulWidget {
@override
_HaberScreenState createState() => _HaberScreenState();
}
class _HaberScreenState extends State<HaberScreen> {
final Completer<WebViewController> _controller =
Completer<WebViewController>();
@override
void initState() {
super.initState();
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
}
int _currentIndex = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(60.0),
child: AppBar(
backgroundColor: Colors.white,
automaticallyImplyLeading: true,
leading: IconButton(
icon: Icon(
Icons.arrow_back_ios,
color: Colors.red,
),
//onPressed:() => Navigator.pop(context, false),
onPressed: () => Navigator.pop(context),
),
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Haberler',
style: TextStyle(color: Colors.red, fontSize: 25.0),
)
],
),
// 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.google.com',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
onProgress: (int progress) {
print("WebView is loading (progress : $progress%)");
},
javascriptChannels: <JavascriptChannel>{
_toasterJavascriptChannel(context),
},
navigationDelegate: (NavigationRequest request) {
if (request.url.startsWith('https://www.youtube.com/')) {
print('blocking navigation to $request}');
return NavigationDecision.prevent;
}
print('allowing navigation to $request');
return NavigationDecision.navigate;
},
onPageStarted: (String url) {
print('Page started loading: $url');
},
onPageFinished: (String url) {
print('Page finished loading: $url');
},
gestureNavigationEnabled: true,
);
}),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: favoriteButton(),
bottomNavigationBar: BottomNavyBar(
selectedIndex: _currentIndex,
showElevation: true,
itemCornerRadius: 24,
curve: Curves.easeIn,
onItemSelected: (index) => setState(() => _currentIndex = index),
items: <BottomNavyBarItem>[
BottomNavyBarItem(
icon: Icon(Icons.apps),
title: Text('Haberler'),
activeColor: Colors.red,
textAlign: TextAlign.center,
),
BottomNavyBarItem(
icon: Icon(Icons.pie_chart),
title: Text('Sektörler'),
activeColor: Colors.red,
textAlign: TextAlign.center,
),
BottomNavyBarItem(
icon: Icon(Icons.monetization_on),
title: Text(
'Kurlar',
),
activeColor: Colors.red,
textAlign: TextAlign.center,
),
BottomNavyBarItem(
icon: Icon(Icons.plagiarism_sharp),
title: Text('Raporlar'),
activeColor: Colors.red,
textAlign: TextAlign.center,
),
BottomNavyBarItem(
icon: Icon(Icons.settings),
title: Text('Ayarlar'),
activeColor: Colors.red,
textAlign: TextAlign.center,
),
],
),
);
}
JavascriptChannel _toasterJavascriptChannel(BuildContext context) {
return JavascriptChannel(
name: 'Toaster',
onMessageReceived: (JavascriptMessage message) {
// ignore: deprecated_member_use
Scaffold.of(context).showSnackBar(
SnackBar(content: Text(message.message)),
);
});
}
Widget favoriteButton() {
return FutureBuilder<WebViewController>(
future: _controller.future,
builder: (BuildContext context,
AsyncSnapshot<WebViewController> controller) {
if (controller.hasData) {
return FloatingActionButton(
onPressed: () async {
final String url = (await controller.data!.currentUrl())!;
// ignore: deprecated_member_use
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('Favorited $url')),
);
},
child: const Icon(
Icons.favorite,
color: Colors.white,
),
);
}
return Container();
});
}
}
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 bool webViewReady =
snapshot.connectionState == ConnectionState.done;
final WebViewController controller = snapshot.data!;
return Row(
children: <Widget>[
IconButton(
icon: const Icon(
Icons.arrow_back_ios,
color: Colors.red,
),
onPressed: !webViewReady
? null
: () async {
if (await controller.canGoBack()) {
await controller.goBack();
} else {
// ignore: deprecated_member_use
Scaffold.of(context).showSnackBar(
const SnackBar(content: Text("Geçmiş Bulunamadı")),
);
return;
}
},
),
IconButton(
icon: const Icon(
Icons.arrow_forward_ios,
color: Colors.red,
),
onPressed: !webViewReady
? null
: () async {
if (await controller.canGoForward()) {
await controller.goForward();
} else {
// ignore: deprecated_member_use
Scaffold.of(context).showSnackBar(
const SnackBar(content: Text("Geçmiş Bulunamadı")),
);
return;
}
},
),
],
);
},
);
}
}
您只提供了一个 widget
作为 body
,因此更改 _currentIndex
不会影响显示的正文。根据此包的示例(在与 PageView 和 PageController 一起使用部分),您可以使用 PageView
来更改显示图像!或者您可以使用 widgets
的列表并显示与 _currentIndex
相关的项目。所以你有两个解决方案:
- 使用
PageView
在您的 body
部分使用 PageView
如下:
child: PageView(
controller: _pageController,
onPageChanged: (index) {
setState(() => _currentIndex = index);
},
children: <Widget>[
Container(color: Colors.blueGrey,),
Container(color: Colors.red,),
Container(color: Colors.green,),
Container(color: Colors.blue,),
],
),
),
不要忘记创建和处理页面控制器:
PageController _pageController;
@override
void initState() {
super.initState();
_pageController = PageController();
}
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
- 使用小部件列表
创建小部件列表:
List<Widget> bodyList = [widget1, widget2, ...]
然后将其作为正文提供:
body: bodyList[_currentIndex]
我正在使用这个 package 通过底部导航栏进行导航,我不明白如何设法在我的屏幕之间导航。如何通过底部导航栏图标在我的屏幕之间导航?
import 'dart:async';
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:bottom_navy_bar/bottom_navy_bar.dart';
class HaberScreen extends StatefulWidget {
@override
_HaberScreenState createState() => _HaberScreenState();
}
class _HaberScreenState extends State<HaberScreen> {
final Completer<WebViewController> _controller =
Completer<WebViewController>();
@override
void initState() {
super.initState();
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
}
int _currentIndex = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(60.0),
child: AppBar(
backgroundColor: Colors.white,
automaticallyImplyLeading: true,
leading: IconButton(
icon: Icon(
Icons.arrow_back_ios,
color: Colors.red,
),
//onPressed:() => Navigator.pop(context, false),
onPressed: () => Navigator.pop(context),
),
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Haberler',
style: TextStyle(color: Colors.red, fontSize: 25.0),
)
],
),
// 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.google.com',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
onProgress: (int progress) {
print("WebView is loading (progress : $progress%)");
},
javascriptChannels: <JavascriptChannel>{
_toasterJavascriptChannel(context),
},
navigationDelegate: (NavigationRequest request) {
if (request.url.startsWith('https://www.youtube.com/')) {
print('blocking navigation to $request}');
return NavigationDecision.prevent;
}
print('allowing navigation to $request');
return NavigationDecision.navigate;
},
onPageStarted: (String url) {
print('Page started loading: $url');
},
onPageFinished: (String url) {
print('Page finished loading: $url');
},
gestureNavigationEnabled: true,
);
}),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: favoriteButton(),
bottomNavigationBar: BottomNavyBar(
selectedIndex: _currentIndex,
showElevation: true,
itemCornerRadius: 24,
curve: Curves.easeIn,
onItemSelected: (index) => setState(() => _currentIndex = index),
items: <BottomNavyBarItem>[
BottomNavyBarItem(
icon: Icon(Icons.apps),
title: Text('Haberler'),
activeColor: Colors.red,
textAlign: TextAlign.center,
),
BottomNavyBarItem(
icon: Icon(Icons.pie_chart),
title: Text('Sektörler'),
activeColor: Colors.red,
textAlign: TextAlign.center,
),
BottomNavyBarItem(
icon: Icon(Icons.monetization_on),
title: Text(
'Kurlar',
),
activeColor: Colors.red,
textAlign: TextAlign.center,
),
BottomNavyBarItem(
icon: Icon(Icons.plagiarism_sharp),
title: Text('Raporlar'),
activeColor: Colors.red,
textAlign: TextAlign.center,
),
BottomNavyBarItem(
icon: Icon(Icons.settings),
title: Text('Ayarlar'),
activeColor: Colors.red,
textAlign: TextAlign.center,
),
],
),
);
}
JavascriptChannel _toasterJavascriptChannel(BuildContext context) {
return JavascriptChannel(
name: 'Toaster',
onMessageReceived: (JavascriptMessage message) {
// ignore: deprecated_member_use
Scaffold.of(context).showSnackBar(
SnackBar(content: Text(message.message)),
);
});
}
Widget favoriteButton() {
return FutureBuilder<WebViewController>(
future: _controller.future,
builder: (BuildContext context,
AsyncSnapshot<WebViewController> controller) {
if (controller.hasData) {
return FloatingActionButton(
onPressed: () async {
final String url = (await controller.data!.currentUrl())!;
// ignore: deprecated_member_use
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('Favorited $url')),
);
},
child: const Icon(
Icons.favorite,
color: Colors.white,
),
);
}
return Container();
});
}
}
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 bool webViewReady =
snapshot.connectionState == ConnectionState.done;
final WebViewController controller = snapshot.data!;
return Row(
children: <Widget>[
IconButton(
icon: const Icon(
Icons.arrow_back_ios,
color: Colors.red,
),
onPressed: !webViewReady
? null
: () async {
if (await controller.canGoBack()) {
await controller.goBack();
} else {
// ignore: deprecated_member_use
Scaffold.of(context).showSnackBar(
const SnackBar(content: Text("Geçmiş Bulunamadı")),
);
return;
}
},
),
IconButton(
icon: const Icon(
Icons.arrow_forward_ios,
color: Colors.red,
),
onPressed: !webViewReady
? null
: () async {
if (await controller.canGoForward()) {
await controller.goForward();
} else {
// ignore: deprecated_member_use
Scaffold.of(context).showSnackBar(
const SnackBar(content: Text("Geçmiş Bulunamadı")),
);
return;
}
},
),
],
);
},
);
}
}
您只提供了一个 widget
作为 body
,因此更改 _currentIndex
不会影响显示的正文。根据此包的示例(在与 PageView 和 PageController 一起使用部分),您可以使用 PageView
来更改显示图像!或者您可以使用 widgets
的列表并显示与 _currentIndex
相关的项目。所以你有两个解决方案:
- 使用
PageView
在您的body
部分使用PageView
如下:
child: PageView(
controller: _pageController,
onPageChanged: (index) {
setState(() => _currentIndex = index);
},
children: <Widget>[
Container(color: Colors.blueGrey,),
Container(color: Colors.red,),
Container(color: Colors.green,),
Container(color: Colors.blue,),
],
),
),
不要忘记创建和处理页面控制器:
PageController _pageController;
@override
void initState() {
super.initState();
_pageController = PageController();
}
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
- 使用小部件列表 创建小部件列表:
List<Widget> bodyList = [widget1, widget2, ...]
然后将其作为正文提供:
body: bodyList[_currentIndex]