原文地址:https://medium.com/flutterdevs/explore-model-viewer-in-flutter-e5988edbfe66
material设计风格的卡片。卡片的边角和阴影有些调整。卡片是用于表示某些关联数据,例如集合,地理区域,膳食,联系方式等。卡片包含有关单个对象的内容和动作。
在本文中,我们将探讨Flutter中 的**Card Selector。**我们将看到如何在flutter应用程序中使用card_selector包来实现带有动画和堆叠卡的卡选择器的演示程序。
地址:https://pub.dev/packages/card_selector
卡选择器是Flutter利用堆栈的窗口小部件选择器。选择器是完全可配置的,动画时间,卡之间的间隙,堆叠卡的尺寸因子。用户可以从左向右或从右向左滑动卡。特定卡上的信息将有所不同。
该演示视频展示了如何在颤动中创建卡选择器。它显示了flutter应用程序中使用card_selector软件包的卡选择器的工作方式。它显示了堆叠的卡片,动画,从左到右或从右到左刷卡。内容将根据卡而改变。一个小部件,用于选择向左或向右滑动的堆叠小部件。它会显示在您的设备上。
将依赖项添加到pubspec-yaml文件。
card_selector: ^0.1.0
添加 asset
assets:
- assets/
导入
import 'package:card_selector/card_selector.dart';
运行 flutter packages get
启用 AndriodX
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true
首先,我们将创建一个虚拟json文件并将其保存在assets文件夹中。
创建动态列表,并命名为_cards。另外,创建动态地图,并命名为_data。
List _cards;
Map _data;
现在,我们将创建initState()。在内部,我们将添加一个json文件,并添加一个_cards的动态列表,该列表等于json解码。我们还将映射一个等于_cards动态列表的_data并包装在setState()中。
@override
void initState() {
super.initState();
DefaultAssetBundle.of(context).loadString("assets/data.json").then((d) {
_cards = json.decode(d);
setState(() => _data = _cards[0]);
});
}
在正文中,我们将添加CardSelector()。在里面,我们将添加cards属性,这意味着将动态_cards点映射列表导航到CardPage()类。toList()。另外,我们将添加mainCardWidth表示列表中第一个元素的宽度,mainCardHeight表示列表中第一个元素的高度,onChanged表示要在更改后的卡片上执行的回调。导航到**setState()**然后导航到_data的索引等于索引的_cards。
CardSelector(
cards: _cards.map((context) => CardPage(context)).toList(),
mainCardWidth: _width,
mainCardHeight: _width * 0.63,
mainCardPadding: -16.0,
onChanged: (i) => setState(() => _data = _cards[i])),
定义**CardPage()类。在此类中,我们将返回ClipRRect。在里面,添加一个容器并从json文件中添加颜色。他的子属性添加了Stack(),**并在内部添加了图像。我们将添加一个列小部件,在内部添加卡的详细信息,例如银行名称,类型,编号和分支。所有数据均来自json文件。
return ClipRRect(
borderRadius: BorderRadius.circular(12.0),
child: Container(
color: Color(_cardDetails['color']),
child: Stack(
children: <Widget>[
Image.asset(
'assets/${_cardDetails['background_layer']}.png',
fit: BoxFit.cover,
height: double.infinity,
width: double.infinity,
),
Padding(
padding: EdgeInsets.all(24.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(_cardDetails['bank'], style: textTheme.title),
Text(_cardDetails['type'].toUpperCase(), style: textTheme.caption),
Expanded(child: Container()),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Expanded(
child: Text(_cardDetails['number'],
style: textTheme.subhead, overflow: TextOverflow.ellipsis),
),
Image.asset('assets/${_cardDetails['branch']}.png', width: 48.0)
],
)
],
),
),
],
),
),
);
定义**AmountPage()类。此类将添加到主页。我们将返回ListView.builder(),**在其中添加itemCount和itemBuilder。在itemBuilder中,如果索引等于零,则返回列小部件。在此小部件中,从json文件添加余额。另外,我们将从json文件中添加金额,模式,时间。
return ListView.builder(
physics: BouncingScrollPhysics(),
itemCount: (_amount['transactions'] as List).length + 1,
itemBuilder: (context, i) {
if (i == 0) {
return Padding(
padding: padding,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Balance', style: TextStyle(color: Colors.black)),
SizedBox(height: 8.0),
Text(_amount['balance'], style: textTheme.display1.apply(color: Colors.white)),
SizedBox(height: 24.0),
Text('Today', style: TextStyle(color: Colors.black)),
],
),
);
}
var transactions = _amount['transactions'][i - 1];
return Padding(
padding: padding,
child: Row(
children: <Widget>[
Icon(Icons.shopping_cart, size: 24.0, color: Colors.blueGrey[600]),
SizedBox(width: 16.0),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(transactions['mode'], style: textTheme.title.apply(color: Colors.white)),
Text(transactions['time'], style: textTheme.caption)
],
),
),
Text(transactions['amount'], style: textTheme.body2.apply(color: Colors.black))
],
),
);
},
);
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:card_selector/card_selector.dart';
import 'package:flutter_card_selector_demo/amount_page.dart';
import 'package:flutter_card_selector_demo/card_page.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
List _cards;
Map _data;
double _width = 0;
@override
void initState() {
super.initState();
DefaultAssetBundle.of(context).loadString("assets/data.json").then((d) {
_cards = json.decode(d);
setState(() => _data = _cards[0]);
});
}
@override
Widget build(BuildContext context) {
if (_cards == null) return Container();
if (_width <= 0) _width = MediaQuery.of(context).size.width - 40.0;
return Scaffold(
backgroundColor: Colors.white70,
appBar: AppBar(
title: Text("Flutter Card Selector Demo"),
automaticallyImplyLeading: false,
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.all(24.0),
child: Text(
"Wallets",
style: TextStyle(color: Colors.white,fontSize: 25)
),
),
SizedBox(height: 20.0),
CardSelector(
cards: _cards.map((context) => CardPage(context)).toList(),
mainCardWidth: _width,
mainCardHeight: _width * 0.63,
mainCardPadding: -16.0,
onChanged: (i) => setState(() => _data = _cards[i])),
SizedBox(height: 10.0),
Expanded(child: AmountPage(_data)),
],
),
);
}
}