我正在尝试制作一个带有旋转木马滑块和动画渐变背景的天气应用程序。要查看预报,用户可以在显示每小时信息的天气卡之间滑动。
我有一个用作背景的动画渐变。此渐变会自动在 3 种颜色的 2 个列表之间变化。当页面首次加载并加载到第一个天气卡的正确颜色列表时,这部分工作正常(例如,如果第一个小时是雨天,背景是雨色,如果第一个小时是晴天,背景是晴天颜色)。
然而,当卡片从一种天气类型变为另一种天气类型时,背景不会改变。我已经尝试解决这个问题 4 天了,但我不知道该怎么做。我已经通过打印确认背景颜色列表是正确的。
我将从下面的主要天气页面发布代码。如果您需要更多信息或任何其他组件,请告诉我。
import 'package:environment/services/weather.dart';
import 'package:flutter/material.dart';
import 'package:animate_gradient/animate_gradient.dart';
import 'package:environment/components/weather_card.dart';
import 'package:carousel_slider/carousel_slider.dart';
class MainWeatherScreen extends StatefulWidget {
const MainWeatherScreen(
{super.key,
this.locationWeather,
this.locationCity,
this.locationPollution});
final dynamic locationWeather;
final dynamic locationCity;
final dynamic locationPollution;
@override
State<MainWeatherScreen> createState() => _MainWeatherScreenState();
}
class _MainWeatherScreenState extends State<MainWeatherScreen> {
WeatherModel weather = WeatherModel();
List<Widget>? weatherCards;
List backgroundColors = [];
int carouselIndex = 0;
List<Color> primaryColors = [];
List<Color> secondaryColors = [];
void changeBackgroundColors(int index) {
setState(() {
primaryColors = backgroundColors[index]['primary'];
secondaryColors = backgroundColors[index]['secondary'];
});
}
@override
void initState() {
super.initState();
updateUI(
widget.locationWeather,
widget.locationCity,
widget.locationPollution,
);
}
void updateUI(
dynamic weatherData,
dynamic cityData,
dynamic pollutionData,
) {
setState(() {
if (weatherData == null) {
weatherCards = [
const WeatherCard(
cityName: 'No Data',
weatherIcon: Icons.broken_image,
temperature: 0,
time: '0.00',
windSpeed: 0.0,
windDegrees: 0,
aqi: 0,
aqiComment: '',
uvi: 0,
uviComment: '',
condition: 0,
sunrise: '',
sunset: '',
)
];
return;
}
weatherCards = weatherCardList(weatherData, cityData, pollutionData);
backgroundColors = weather.getBackgroundColors(weatherData);
primaryColors = backgroundColors[0]['primary'];
secondaryColors = backgroundColors[0]['secondary'];
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: AnimateGradient(
primaryColors: primaryColors,
secondaryColors: secondaryColors,
child: SafeArea(
child: Center(
child: Column(
children: [
Row(
children: <Widget>[
TextButton(
onPressed: () async {
var weatherData = await weather.getLocationWeather();
var cityData = await weather.getCityName();
var pollutionData =
await weather.getLocationPollution();
updateUI(weatherData, cityData, pollutionData);
},
child: const Icon(
Icons.near_me,
color: Colors.white,
size: 50.0,
),
),
],
),
CarouselSlider(
items: weatherCards,
options: CarouselOptions(
viewportFraction: 1.0,
scrollDirection: Axis.horizontal,
height: 600,
enableInfiniteScroll: false,
onPageChanged: (index, reason) {
setState(() {
carouselIndex = index;
changeBackgroundColors(index);
});
},
),
),
],
),
),
),
),
);
}
}
我尝试创建一个函数来更新主要颜色和次要颜色,当在轮播滑块上触发 onPageChanged 时调用该函数。我希望这会更新 AnimateGradient 上的参数,但颜色在应用程序上保持不变。
根据您的代码,changeBackgroundColors() 函数似乎正在适当地更新 primaryColors 和 secondaryColors 列表。然而,问题可能是 AnimateGradient 小部件没有接收到更改后的颜色。
要解决这个问题,您必须在 build() 方法中包含修改后的 primaryColors 和 secondaryColors 列表,并将它们提供给 AnimateGradient 小部件。您可以通过将 AnimateGradient 小部件存储在变量中并随着颜色的变化更改其属性来实现此目的。
这是应该运行的 build() 方法的更新迭代:
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Column(
children: [
Row(
children: <Widget>[
TextButton(
onPressed: () async {
var weatherData = await weather.getLocationWeather();
var cityData = await weather.getCityName();
var pollutionData =
await weather.getLocationPollution();
updateUI(weatherData, cityData, pollutionData);
},
child: const Icon(
Icons.near_me,
color: Colors.white,
size: 50.0,
),
),
],
),
AnimateGradient(
primaryColors: primaryColors,
secondaryColors: secondaryColors,
child: CarouselSlider(
items: weatherCards,
options: CarouselOptions(
viewportFraction: 1.0,
scrollDirection: Axis.horizontal,
height: 600,
enableInfiniteScroll: false,
onPageChanged: (index, reason) {
setState(() {
carouselIndex = index;
changeBackgroundColors(index);
});
},
),
),
),
],
),
),
),
);
}
请注意,我将 AnimateGradient 小部件移到了 SafeArea 小部件之外,并用它包裹了 CarouselSlider 小部件。这允许我们在颜色改变时更新 AnimateGradient 的属性。