Я потратил почти два дня, пытаясь выяснить, как сделать прокручиваемую веб-страницу во вкладке во Флаттере. Я понимаю, что виджет TabBarWiew должен быть заключен в виджет с фиксированной высотой, что может быть для этого? Я не знаю, может ли это помочь, но мой minSdkVersion равен 16, а targetSdkVersion равен 28 , и это вывод команды flutter --version
Flutter 1.12.13+hotfix.5 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 27321ebbad (10 weeks ago) • 2019-12-10 18:15:01 -0800
Engine • revision 2994f7e1e6
Tools • Dart 2.7.0
Ниже приведен код страницы, которую я создаю.
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Pays'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
double screenHeight = MediaQuery.of(context).size.height;
final List<Tab> myTabs = <Tab>[
Tab(text: 'LEFT'),
Tab(text: 'RIGHT'),
];
TabController _tabController;
@override
void initState() {
super.initState();
_tabController = TabController(vsync: this, length: myTabs.length);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
backgroundColor: Colors.red[800],
),
body: Container(
color: Colors.grey[100],
child: ListView(
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Image.network(
'https://lh3.googleusercontent.com/proxy/dThF-49TD0synkY_v1F0mh2HQFp_P5bxYvdLI1msK-aD7h4CtzctJpJP3Cm89LyAWAg21xqvUDdQjdRi2yDH4iEU1wr_LT3BO8iOmx141QOtzXPgUpXW7ulAlHUtAJ4Z0yea_Qr4sWZfApns3VuAbxNcTNISWdStSoJEZ9-OmRypu-3YTQ',
height: 150,
fit: BoxFit.fitWidth,
alignment: Alignment.topCenter,
filterQuality: FilterQuality.high,
)),
],
),
SizedBox(
height: 1,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Text('237',
style: TextStyle(
color: Colors.black,
fontSize: 35,
fontWeight: FontWeight.bold)),
SizedBox(
width: 5,
),
Image.network(
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQJrM_W9cpz33KFyqL_L-meeCuH_Kyufoohxjlh06XdBnIbel0j&s',
height: 30,
),
Spacer(),
Image.network(
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTwnqIeW1RJHtAhRE7ccZ-4s4ymEh5zHRYAdidO7p9GfDnOwziY&s',
height: 50,
)
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(
'Cameroun',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontSize: 25,
fontWeight: FontWeight.bold),
)
]),
),
SizedBox(height: 5),
NestedTabBar()
],
)),
// This trailing comma makes auto-formatting nicer for build methods.
);
}
}
class NestedTabBar extends StatefulWidget {
@override
_NestedTabBarState createState() => _NestedTabBarState();
}
class _NestedTabBarState extends State<NestedTabBar>
with TickerProviderStateMixin {
TabController _nestedTabController;
ScrollController _scrollController;
@override
void initState() {
//_scrollController = ScrollController();
super.initState();
_nestedTabController = new TabController(length: 2, vsync: this);
//_nestedTabController.addListener(_handleTabSelection);
}
@override
void dispose() {
_nestedTabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
double screenHeight = MediaQuery.of(context).size.height;
return Column(
children: <Widget>[
TabBar(
controller: _nestedTabController,
indicatorColor: Colors.teal,
labelColor: Colors.teal,
unselectedLabelColor: Colors.black54,
isScrollable: true,
tabs: <Widget>[
Tab(
text: "A propos & Statistiques",
),
Tab(
text: "Wiki",
)
],
),
Container(
height: screenHeight * 0.9,
margin: EdgeInsets.only(left: 8.0, right: 8.0),
child: TabBarView(
controller: _nestedTabController,
children: <Widget>[
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
),
child: Text('Simple text')),
/*GestureDetector(
child: MyWebView(selectedUrl: 'https://fr.wikipedia.org/wiki/Lewis_Hamilton'),
),*/
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
),
child: MyWebView(
selectedUrl: 'https://fr.wikipedia.org/wiki/Cameroun'),
),
],
),
),
// MyWebView(selectedUrl: 'https://fr.wikipedia.org/wiki/Lewis_Hamilton')
],
);
}
}
class MyWebView extends StatefulWidget {
final String selectedUrl;
MyWebView({
@required this.selectedUrl,
});
@override
_MyWebViewState createState() => _MyWebViewState();
}
class _MyWebViewState extends State<MyWebView> {
Completer<WebViewController> _controller;
@override
void initState() {
super.initState();
_controller = Completer<WebViewController>();
}
@override
void dispose() {
super.dispose();
_controller = null;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: WebView(
initialUrl: widget.selectedUrl,
gestureRecognizers: Set()
..add(Factory<VerticalDragGestureRecognizer>(
() => VerticalDragGestureRecognizer())),
gestureNavigationEnabled: true,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
));
}
}