I希望在每个页面视图上显示一辆汽车的完整图像和另一辆汽车的半幅图像,当用户更改页面时,汽车之间会有动画过渡。为了更好地理解我的问题,下面是我的代码:
TabBarView(
children: serviceCategories.map((e) {
return PageView(
children: e.services
.map((e) => SizedBox(
height: 225,
//width: MediaQuery.of(context).size.width * 0.1,
child: PageView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) =>
ServiceItemView(
isSelected: e.id ==
(mainBloc.state as OrderPreview)
.selectedService
?.id,
service: e,
currency: currency),
itemCount: serviceCategories
.map((e) => e)
.toList()
.length,
),
) /*ServiceItemView(
service: e,
isSelected: e.id ==
(mainBloc.state as OrderPreview)
.selectedService
?.id,
currency: currency,
)*/
)
.toList(),
);
}).toList(),
),
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:ridy/app_colors.dart';
import '../config.dart';
import '../graphql/generated/graphql_api.graphql.dart';
import 'package:velocity_x/velocity_x.dart';
import 'package:intl/intl.dart';
import 'package:client_shared/theme/theme.dart';
import 'bloc/main_bloc.dart';
class ServiceItemView extends StatelessWidget {
final bool isSelected;
final GetFare$Query$CalculateFareDTO$ServiceCategory$Service service;
final String currency;
const ServiceItemView(
{Key? key,
required this.isSelected,
required this.service,
required this.currency})
: super(key: key);
@override
Widget build(BuildContext context) {
final mainBloc = context.read<MainBloc>();
return GestureDetector(
onTap: () => mainBloc.add(SelectService(service)),
child: AnimatedContainer(
duration: const Duration(milliseconds: 250),
padding: const EdgeInsets.symmetric(horizontal: 4),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: isSelected
? CustomTheme.primaryColors.shade100
: CustomTheme.primaryColors.shade50),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: 150,
width: MediaQuery.of(context).size.width * 0.6,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
serverUrl + service.media.address,
))),
),
// Image.network(
// serverUrl + service.media.address,
// width: MediaQuery.of(context).size.width,
// height: 150,
// ),
Row(
children: [
Text(
service.cost.toStringAsFixed(2),
style: Theme.of(context).textTheme.titleLarge?.copyWith(
fontSize: 25,
fontWeight: FontWeight.normal,
decoration: (service.costAfterCoupon != null &&
service.cost != service.costAfterCoupon)
? TextDecoration.lineThrough
: TextDecoration.none,
color: (service.costAfterCoupon != null &&
service.cost != service.costAfterCoupon)
? CustomTheme.neutralColors.shade300
: //CustomTheme.neutralColors.shade800
AppColors.appMainColor),
),
Text(
' $currency',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontSize: 25,
fontWeight: FontWeight.normal,
color: (service.costAfterCoupon != null &&
service.cost != service.costAfterCoupon)
? CustomTheme.neutralColors.shade300
: //CustomTheme.neutralColors.shade800
AppColors.appMainColor,
),
),
],
),
if (service.costAfterCoupon != null &&
service.cost != service.costAfterCoupon)
Row(
children: [
Text(
service.costAfterCoupon.toString(),
style: Theme.of(context)
.textTheme
.titleMedium
?.copyWith(color: const Color(0xff108910)),
),
Text(
currency,
style: Theme.of(context)
.textTheme
.titleMedium
?.copyWith(color: const Color(0xff108910)),
),
],
).pOnly(top: 4),
// Text(
// NumberFormat.simpleCurrency(name: currency).format(service.cost),
// style: Theme.of(context).textTheme.titleMedium?.copyWith(
// decoration: (service.costAfterCoupon != null &&
// service.cost != service.costAfterCoupon)
// ? TextDecoration.lineThrough
// : TextDecoration.none,
// color: (service.costAfterCoupon != null &&
// service.cost != service.costAfterCoupon)
// ? CustomTheme.neutralColors.shade300
// : CustomTheme.neutralColors.shade800),
// ),
// if (service.costAfterCoupon != null &&
// service.cost != service.costAfterCoupon)
// Text(
// NumberFormat.simpleCurrency(name: currency)
// .format(service.costAfterCoupon),
// style: Theme.of(context)
// .textTheme
// .titleMedium
// ?.copyWith(color: const Color(0xff108910)),
// ).pOnly(top: 4)
],
),
// child: Row(
// children: [
// Image.network(
// serverUrl + service.media.address,
// width: 75,
// height: 75,
// ),
// Padding(
// padding: const EdgeInsets.symmetric(horizontal: 8),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Text(
// service.name,
// style: Theme.of(context).textTheme.titleMedium,
// ),
// if (service.description?.isNotEmpty ?? false)
// Text(
// service.description ?? "",
// style: Theme.of(context).textTheme.labelMedium,
// ).pOnly(top: 4)
// ],
// ),
// ),
// const Spacer(),
// Column(
// crossAxisAlignment: CrossAxisAlignment.center,
// children: [
// Text(
// NumberFormat.simpleCurrency(name: currency)
// .format(service.cost),
// style: Theme.of(context).textTheme.titleMedium?.copyWith(
// decoration: (service.costAfterCoupon != null &&
// service.cost != service.costAfterCoupon)
// ? TextDecoration.lineThrough
// : TextDecoration.none,
// color: (service.costAfterCoupon != null &&
// service.cost != service.costAfterCoupon)
// ? CustomTheme.neutralColors.shade300
// : CustomTheme.neutralColors.shade800),
// ),
// if (service.costAfterCoupon != null &&
// service.cost != service.costAfterCoupon)
// Text(
// NumberFormat.simpleCurrency(name: currency)
// .format(service.costAfterCoupon),
// style: Theme.of(context)
// .textTheme
// .titleMedium
// ?.copyWith(color: const Color(0xff108910)),
// ).pOnly(top: 4)
// ],
// ).pOnly(top: 4, right: 8)
// ],
// ),
),
);
}
}
我该怎么办?这是客户应用程序。当用户选择乘坐类型的汽车形象应该改变这种形式
2条答案
按热度按时间knpiaxh11#
Ramji的答案可能也适用于您,但您也可以在不使用软件包的情况下完成。为此,您只需要为pageview定义一个控制器,并在此控制器中指定viewportFraction值。
nnsrf1az2#
你想要的过渡效果被称为carousel effect,flutter有很多很棒的包,我们可以使用flutter_carousel_widget 2.0.4。我添加了一个简短的示例,其中包含特定的属性,可以给予您提供所需的效果。欲了解更多关于这一点,请访问官方网站。
完整代码:-
输出:-