我正在尝试实现一个下拉按钮,让用户在我的应用程序的语言之间切换,相应的 Webview 容器将更改以匹配所选语言。我试图通过创建一个 _renderWebviewBox1() 函数来实现这一点,该函数返回与当前所选语言匹配的 Webview 控制器。
String? _value = "English";
_renderWebviewBox1() {
if (_value == "English") {
return WebViewWidget(controller: _controller);
} else if (_value == "Mi'gmaq") {
return WebViewWidget(controller: _controller1Mig);
} else {
print("No translation yet");
return null;
}
}
这是我的完整代码:
import 'package:flutter/material.dart';
import 'package:flutter_webview_practice/routes.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: MainPage(),
initialRoute: RouteManager.homePage,
onGenerateRoute: RouteManager.generateRoute,
);
}
}
class MainPage extends StatefulWidget {
const MainPage({super.key});
@override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
late final WebViewController _controller = WebViewController()
..setBackgroundColor(Colors.transparent)
..setJavaScriptMode(JavaScriptMode.unrestricted)
..loadFlutterAsset("assets/aligns/hunter-3-align1.html")
..setNavigationDelegate(
NavigationDelegate(
onProgress: (int progress) {
debugPrint('WebView is loading (progress : $progress%)');
},
),
);
late final WebViewController _controller2 = WebViewController()
..setBackgroundColor(Colors.transparent)
..setJavaScriptMode(JavaScriptMode.unrestricted)
..loadFlutterAsset("assets/aligns/hunter-3-align2.html")
..setNavigationDelegate(
NavigationDelegate(
onProgress: (int progress) {
debugPrint('WebView is loading (progress : $progress%)');
},
),
);
late final WebViewController _controller1Mig = WebViewController()
..setBackgroundColor(Colors.transparent)
..setJavaScriptMode(JavaScriptMode.unrestricted)
..loadFlutterAsset("assets/aligns/hunter-3-align1-mig.html")
..setNavigationDelegate(
NavigationDelegate(
onProgress: (int progress) {
debugPrint('WebView is loading (progress : $progress%)');
},
),
);
late final WebViewController _controller2Mig = WebViewController()
..setBackgroundColor(Colors.transparent)
..setJavaScriptMode(JavaScriptMode.unrestricted)
..loadFlutterAsset("assets/aligns/hunter-3-align2-mig.html")
..setNavigationDelegate(
NavigationDelegate(
onProgress: (int progress) {
debugPrint('WebView is loading (progress : $progress%)');
},
),
);
String? _value = "English";
_renderWebviewBox1() {
if (_value == "English") {
return WebViewWidget(controller: _controller);
} else if (_value == "Mi'gmaq") {
return WebViewWidget(controller: _controller1Mig);
} else {
print("No translation yet");
return null;
}
}
_renderWebviewBox2() {
if (_value == "English") {
return WebViewWidget(controller: _controller2);
} else if (_value == "Mi'gmaq") {
return WebViewWidget(controller: _controller2Mig);
} else {
print("No translation yet");
return null;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: FittedBox(
alignment: Alignment.center,
fit: BoxFit.contain,
child: Column(
children: [
DropdownButton<String>(
value: _value,
items: <String>[
"English",
"Mi'gmaq",
"Wolastoqey",
].map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (String? newValue) {
if (newValue != _value) {
switch (newValue) {
case "Mi'gmaq":
_value = "Mi'gmaq";
break;
case "English":
_value = "English";
break;
case "Wolastoqey":
_value = "Wolastoqey";
break;
}
}
setState(() {
_value = newValue;
});
},
),
Stack(
children: [
Container(
width: 650,
height: 500,
child: const Image(
image: AssetImage("assets/images/hunterChoice3.jpg"),
),
),
Positioned(
left: 120,
right: 10,
top: 10,
bottom: 10,
child: Container(
width: 325,
height: 500,
child: _renderWebviewBox1(),
),
),
Positioned(
left: 20,
right: 90,
top: 420,
child: Container(
width: 325,
height: 500,
child: _renderWebviewBox2(),
),
),
],
),
],
),
),
),
);
}
}
但是,目前,虽然下拉按钮会更新,但页面不会重建,因此 _renderWebviewBox1() 和 _renderWebviewBox2() 只被调用一次。我应该如何实现 setState() 以便每次更改下拉按钮时重新构建页面?
我尝试将 setState() 放在下拉按钮小部件中 onChanged 属性的每个 switch 语句中,但这也不会重建页面。
正如Peter Koltai提到的,您应该使用
setState
方法让应用程序知道它必须重建,但没有必要直接在_value
方法中使用build
。 build
方法执行的时候,也是每次都执行这两个函数。
我假设如果您为每个
WebViewWidget
添加不同的密钥,它将正常重建。
此外,您完全不需要
switch
声明,它可以删除,因为它什么都不做:
onChanged: (String? newValue) {
if (newValue != _value) {
setState(() {
_value = newValue;
});
}
此外,当您到处使用复制粘贴代码时,请考虑创建函数或方法以减少代码重复。