我知道OutlineButton是旧版本,而新版本是OutlinedButton。
我的项目: 环境: sdk: ”
我的安装 : [√] 颤振通道稳定,3.0.5,
import 'package:cached_network_image/cached_network_image.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:mvc_pattern/mvc_pattern.dart';
import '../../generated/l10n.dart';
import '../controllers/product_controller.dart';
import '../elements/AddToCartAlertDialog.dart';
import '../elements/CircularLoadingWidget.dart';
import '../elements/OptionItemWidget.dart';
import '../elements/ReviewsListWidget.dart';
import '../elements/ShoppingCartFloatButtonWidget.dart';
import '../helpers/helper.dart';
import '../models/media.dart';
import '../models/route_argument.dart';
import '../repository/user_repository.dart';
// ignore: must_be_immutable
class ProductWidget extends StatefulWidget {
RouteArgument routeArgument;
ProductWidget({Key key, this.routeArgument}) : super(key: key);
@override
_ProductWidgetState createState() {
return _ProductWidgetState();
}
}
class _ProductWidgetState extends StateMVC<ProductWidget> {
ProductController _con;
_ProductWidgetState() : super(ProductController()) {
_con = controller;
}
@override
void initState() {
_con.listenForProduct(productId: widget.routeArgument.id);
_con.listenForCart();
_con.listenForFavorite(productId: widget.routeArgument.id);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: _con.scaffoldKey,
body: _con.product == null || _con.product?.image == null || _con.product?.images == null
? CircularLoadingWidget(height: 500)
: RefreshIndicator(
onRefresh: _con.refreshProduct,
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Container(
margin: EdgeInsets.only(bottom: 125),
padding: EdgeInsets.only(bottom: 15),
child: CustomScrollView(
primary: true,
shrinkWrap: false,
slivers: <Widget>[
SliverAppBar(
backgroundColor: Theme.of(context).accentColor.withOpacity(0.9),
expandedHeight: 275,
elevation: 0,
iconTheme: IconThemeData(color: Theme.of(context).primaryColor),
flexibleSpace: FlexibleSpaceBar(
collapseMode: CollapseMode.parallax,
background: Stack(
alignment: AlignmentDirectional.bottomCenter,
children: <Widget>[
CarouselSlider(
options: CarouselOptions(
autoPlay: true,
autoPlayInterval: Duration(seconds: 7),
height: 300,
enableInfiniteScroll: false,
viewportFraction: 1.0,
onPageChanged: (index, reason) {
setState(() {
_con.current = index;
});
},
),
items: _con.product.images.map((Media image) {
return Builder(
builder: (BuildContext context) {
return CachedNetworkImage(
height: 300,
width: double.infinity,
fit: BoxFit.cover,
imageUrl: image.url,
placeholder: (context, url) => Image.asset(
'assets/img/loading.gif',
fit: BoxFit.cover,
width: double.infinity,
height: 300,
),
errorWidget: (context, url, error) => Icon(Icons.error_outline),
);
},
);
}).toList(),
),
Visibility(
visible: _con.product.images.length > 1,
child: Container(
//margin: EdgeInsets.symmetric(vertical: 22, horizontal: 42),
child: Row(
mainAxisSize: MainAxisSize.min,
children: _con.product.images.map((Media image) {
return Container(
width: 20.0,
height: 5.0,
margin: EdgeInsets.symmetric(vertical: 20.0, horizontal: 2.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(10),
),
color: _con.current == _con.product.images.indexOf(image)
? Theme.of(context).accentColor
: Theme.of(context).primaryColor.withOpacity(0.4)),
);
}).toList(),
),
),
),
],
),
),
),
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15),
child: Wrap(
runSpacing: 8,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 3,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
_con.product?.name ?? '',
overflow: TextOverflow.ellipsis,
maxLines: 2,
style: Theme.of(context).textTheme.headline3,
),
Text(
_con.product?.market?.name ?? '',
overflow: TextOverflow.ellipsis,
maxLines: 2,
style: Theme.of(context).textTheme.bodyText2,
),
],
),
),
Expanded(
flex: 1,
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Helper.getPrice(
_con.product.price,
context,
style: Theme.of(context).textTheme.headline2,
),
_con.product.discountPrice > 0
? Helper.getPrice(_con.product.discountPrice, context,
style: Theme.of(context).textTheme.bodyText2.merge(TextStyle(decoration: TextDecoration.lineThrough)))
: SizedBox(height: 0),
],
),
),
],
),
Row(
children: <Widget>[
Container(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 3),
decoration: BoxDecoration(
color: Helper.canDelivery(_con.product.market) && _con.product.deliverable ? Colors.green : Colors.orange,
borderRadius: BorderRadius.circular(24)),
child: Helper.canDelivery(_con.product.market) && _con.product.deliverable
? Text(
S.of(context).deliverable,
style: Theme.of(context).textTheme.caption.merge(TextStyle(color: Theme.of(context).primaryColor)),
)
: Text(
S.of(context).not_deliverable,
style: Theme.of(context).textTheme.caption.merge(TextStyle(color: Theme.of(context).primaryColor)),
),
),
Expanded(child: SizedBox(height: 0)),
Visibility(
visible: _con.product.capacity != null && _con.product.capacity != "null",
child: Container(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 3),
decoration: BoxDecoration(color: Theme.of(context).focusColor, borderRadius: BorderRadius.circular(24)),
child: Text(
_con.product.capacity + " " + _con.product.unit,
style: Theme.of(context).textTheme.caption.merge(TextStyle(color: Theme.of(context).primaryColor)),
)),
),
SizedBox(width: 5),
Visibility(
visible: _con.product.packageItemsCount != null && _con.product.packageItemsCount != "null",
child: Container(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 3),
decoration: BoxDecoration(color: Theme.of(context).focusColor, borderRadius: BorderRadius.circular(24)),
child: Text(
_con.product.packageItemsCount + " " + S.of(context).items,
style: Theme.of(context).textTheme.caption.merge(TextStyle(color: Theme.of(context).primaryColor)),
)),
),
],
),
Divider(height: 20),
Text(Helper.skipHtml(_con.product.description)),
if (_con.product.optionGroups.isNotEmpty)
ListTile(
dense: true,
contentPadding: EdgeInsets.symmetric(vertical: 10),
leading: Icon(
Icons.add_circle_outline,
color: Theme.of(context).hintColor,
),
title: Text(
S.of(context).options,
style: Theme.of(context).textTheme.subtitle1,
),
subtitle: Text(
S.of(context).select_options_to_add_them_on_the_product,
style: Theme.of(context).textTheme.caption,
),
),
ListView.separated(
padding: EdgeInsets.all(0),
itemBuilder: (context, optionGroupIndex) {
var optionGroup = _con.product.optionGroups.elementAt(optionGroupIndex);
print("SIZE:::${_con.product.options.where((option) => option.optionGroupId == optionGroup.id).length}");
return Wrap(
children: <Widget>[
ListTile(
dense: true,
contentPadding: EdgeInsets.symmetric(vertical: 0),
leading: Icon(
Icons.add_circle_outline,
color: Theme.of(context).hintColor,
),
title: Text(
optionGroup.name,
style: Theme.of(context).textTheme.subtitle1,
),
),
ListView.separated(
padding: EdgeInsets.all(0),
itemBuilder: (context, optionIndex) {
return OptionItemWidget(
option: _con.product.options.where((option) => option.optionGroupId == optionGroup.id).elementAt(optionIndex),
onChanged: _con.calculateTotal,
);
},
separatorBuilder: (context, index) {
return SizedBox(height: 20);
},
itemCount: _con.product.options.where((option) => option.optionGroupId == optionGroup.id).length,
primary: false,
shrinkWrap: true,
),
],
);
},
separatorBuilder: (context, index) {
return SizedBox(height: 20);
},
itemCount: _con.product.optionGroups.length,
primary: false,
shrinkWrap: true,
),
/*ListTile(
dense: true,
contentPadding: EdgeInsets.symmetric(vertical: 10),
leading: Icon(
Icons.recent_actors_outlined,
color: Theme.of(context).hintColor,
),
title: Text(
S.of(context).reviews,
style: Theme.of(context).textTheme.subtitle1,
),
),
ReviewsListWidget(
reviewsList: _con.product.productReviews,
),*/
],
),
),
),
],
),
),
Positioned(
top: 32,
right: 20,
child: _con.loadCart
? SizedBox(
width: 60,
height: 60,
child: RefreshProgressIndicator(),
)
: ShoppingCartFloatButtonWidget(
iconColor: Theme.of(context).primaryColor,
labelColor: Theme.of(context).hintColor,
routeArgument: RouteArgument(param: '/Product', id: _con.product.id),
),
),
Positioned(
bottom: 0,
child: Container(
height: 150,
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 8),
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.only(topRight: Radius.circular(20), topLeft: Radius.circular(20)),
boxShadow: [BoxShadow(color: Theme.of(context).focusColor.withOpacity(0.15), offset: Offset(0, -2), blurRadius: 5.0)]),
child: SizedBox(
width: MediaQuery.of(context).size.width - 40,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Text(
S.of(context).quantity,
style: Theme.of(context).textTheme.subtitle1,
),
),
Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
IconButton(
onPressed: () {
_con.decrementQuantity();
},
iconSize: 30,
padding: EdgeInsets.symmetric(horizontal: 5, vertical: 10),
icon: Icon(Icons.remove_circle_outline),
color: Theme.of(context).hintColor,
),
Text(_con.quantity.toString(), style: Theme.of(context).textTheme.subtitle1),
IconButton(
onPressed: () {
_con.incrementQuantity();
},
iconSize: 30,
padding: EdgeInsets.symmetric(horizontal: 5, vertical: 10),
icon: Icon(Icons.add_circle_outline),
color: Theme.of(context).hintColor,
)
],
),
],
),
SizedBox(height: 10),
Row(
children: <Widget>[
Expanded(
child: _con.favorite?.id != null
? OutlineButton(
onPressed: () {
_con.removeFromFavorite(_con.favorite);
},
padding: EdgeInsets.symmetric(vertical: 14),
color: Theme.of(context).primaryColor,
shape: StadiumBorder(),
borderSide: BorderSide(color: Theme.of(context).accentColor),
child: Icon(
Icons.favorite,
color: Theme.of(context).accentColor,
))
: MaterialButton(
elevation: 0,
onPressed: () {
if (currentUser.value.apiToken == null) {
Navigator.of(context).pushNamed("/Login");
} else {
_con.addToFavorite(_con.product);
}
},
padding: EdgeInsets.symmetric(vertical: 14),
color: Theme.of(context).accentColor,
shape: StadiumBorder(),
child: Icon(
Icons.favorite_outline,
color: Theme.of(context).primaryColor,
)),
),
SizedBox(width: 10),
Stack(
fit: StackFit.loose,
alignment: AlignmentDirectional.centerEnd,
children: <Widget>[
SizedBox(
width: MediaQuery.of(context).size.width - 110,
child: MaterialButton(
elevation: 0,
onPressed: () {
if (currentUser.value.apiToken == null) {
Navigator.of(context).pushNamed("/Login");
} else {
if (_con.isSameMarkets(_con.product)) {
_con.addToCart(_con.product);
} else {
showDialog(
context: context,
builder: (BuildContext context) {
// return object of type Dialog
return AddToCartAlertDialogWidget(
oldProduct: _con.carts.elementAt(0)?.product,
newProduct: _con.product,
onPressed: (product, {reset: true}) {
return _con.addToCart(_con.product, reset: true);
});
},
);
}
}
},
padding: EdgeInsets.symmetric(vertical: 14),
color: Theme.of(context).accentColor,
shape: StadiumBorder(),
child: Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Text(
S.of(context).add_to_cart,
textAlign: TextAlign.start,
style: TextStyle(color: Theme.of(context).primaryColor),
),
),
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Helper.getPrice(
_con.total,
context,
style: Theme.of(context).textTheme.headline4.merge(TextStyle(color: Theme.of(context).primaryColor)),
),
)
],
),
],
),
SizedBox(height: 10),
],
),
),
),
)
],
),
),
);
}
}
outlinedButton没有像color borderside这样的属性,你可以使用style属性给它颜色和边框。
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(Colors.green),
),
将以下样式添加到您的outlinedButton中,它将为您工作。
style: ButtonStyle(
padding: MaterialStateProperty.all(
EdgeInsets.symmetric(vertical: 14),
),
backgroundColor:
MaterialStateProperty.all(Theme.of(context).primaryColor),
shape: MaterialStateProperty.all(
StadiumBorder(),
),
),
本文向大家介绍wxWidgets自定义按钮的方法,包括了wxWidgets自定义按钮的方法的使用技巧和注意事项,需要的朋友参考一下 场景: 1.现在的软件上的按钮都不是标准的按钮了,因为基本上是贴图上去的,正常情况下一种图片,鼠标移上去之后按钮显示另一种效果,按下去之后又是另一种效果。 2.wx的做法其实和mfc的按钮原理是一样的,就是给按钮贴图和重绘背景。 以下是源文件. dh_bitmap_b
本文向大家介绍C# WPF 自定义按钮的方法,包括了C# WPF 自定义按钮的方法的使用技巧和注意事项,需要的朋友参考一下 本文介绍WPF一种自定义按钮的方法。 实现效果 使用图片做按钮背景; 自定义鼠标进入时效果; 自定义按压效果; 自定义禁用效果 实现效果如下图所示: 实现步骤 创建CustomButton.cs,继承自Button; 创建一个资源文件ButtonStyles.xaml; 在资
Good day我不确定发生了什么我怀疑eclipse,但在UserDetailsServiceImpl中它是定义的,因为我实现了spring的UserDetails服务,下面是我的代码 这是让人头痛的一行“UserDetails UserDetails=userDetailsService.loadUserByUsername(username)”提前感谢您
Emacs 的大纲模式(Outline mode),是一个十分有用的模式。如果工程规模比较大,你应该用大纲来组织它。 大纲模式通常作为辅模式使用,M-x outline-minor-mode启用。 大纲模式可以根据代码的语法对结构进行识别,但是这种自动模式工作的不是很好,而且不够灵活 另一种工作方式是查找特定的字串,来组织文档的结构。这种工作方式是可控制的,不过需要手动加入这些作为结构标识的字串。
问题内容: 我正在尝试对页面登录进行编码,但在此错误中我处于停止状态 PLIZ在这里告诉我错了事 问题答案: 用于准备的语句。例如 您正在尝试直接在主数据库对象上执行查询。对于PDO,这意味着 您确实应该研究准备好的语句。您很容易受到SQL注入攻击的影响,并且由于您从一开始就使用PDO,因此不编写安全查询基本上是不可原谅的。