Futter時間軸Timelineの実現
まず時間軸効果図を見ます。
実現の難しさは左のタイムラインで、右のイベントの説明はListViewです。よく見るとListViewの一つのアイテムに丸がついています。これらを理解したいなら、私たちは円と右のイベントを一つのlistitemとして実現できます。左の縦線には二つの実現方法があります。
1)listItemはRowで、Rowには縦線が含まれています。
2)Stckが実現し、Stockには二つのchild widgetがあります。一つは縦線で、一つはListViewです。
本文は簡単に第二種類でそれを実現します。
コードを直接見る
ここでFutter時間軸Timelineの実現に関する記事を紹介します。Futter時間軸に関する詳細な内容は以前の文章を検索したり、下記の関連記事を見たりしてください。これからもよろしくお願いします。
実現の難しさは左のタイムラインで、右のイベントの説明はListViewです。よく見るとListViewの一つのアイテムに丸がついています。これらを理解したいなら、私たちは円と右のイベントを一つのlistitemとして実現できます。左の縦線には二つの実現方法があります。
1)listItemはRowで、Rowには縦線が含まれています。
2)Stckが実現し、Stockには二つのchild widgetがあります。一つは縦線で、一つはListViewです。
本文は簡単に第二種類でそれを実現します。
@override
Widget build(BuildContext context) {
return Card(
elevation: 0,
margin: EdgeInsets.symmetric(horizontal: 15, vertical: 50),
child: Stack(
fit: StackFit.loose,
children: <Widget>[
//
Positioned(
left: 21,
top: 15,
bottom: 15,
child: VerticalDivider(
width: 1,
),
),
//
ListView.separated(
padding: EdgeInsets.zero,
itemCount: events.length,
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return FlowEventRow(events[index]);
},
separatorBuilder: (BuildContext context, int index) {
return Divider(
height: 1,
indent: 45,
);
},
),
],
),
);
}
コードは簡単です。あまり説明しません。主にイベント行Floweventrowはどうやって左の円を実現しますか?コードを直接見る
class FlowEvent {
const FlowEvent({
this.advise,
@required this.date,
@required this.author,
this.isCompleted = true,
});
final String advise;
final DateTime date;
final bool isCompleted;
final String author;
bool get hasAdvise =>
isCompleted && advise != null ? advise?.isNotEmpty : false;
}
@immutable
class FlowEventRow extends StatelessWidget {
const FlowEventRow(this.event);
final FlowEvent event;
double get circleRadius => event.isCompleted ? 8 : 6;
Color get circleColor =>
event.isCompleted ? const Color(0xFF40BE7F) : const Color(0xFFD5D5D5);
@override
Widget build(BuildContext context) {
final Color dimColor = const Color(0xFFC5C5C5);
final Color highlightColor = const Color(0xFF40BE7F);
return Padding(
padding: EdgeInsets.symmetric(vertical: 10),
child: Row(
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(horizontal: 22.0 - circleRadius),
child: Container(
width: circleRadius * 2,
height: circleRadius * 2,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: circleColor,
),
),
),
Expanded(
child: Padding(
padding: EdgeInsets.only(left: 0, right: 15),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Text(
' ',
style: TextStyle(
fontSize: 13,
color:
event.isCompleted ? highlightColor : dimColor,
),
),
),
Text(
DateUtils.formatDay(event.date, withHms: true),
style: Theme.of(context)
.textTheme
.caption
.copyWith(color: dimColor),
)
],
),
...event.hasAdvise
? [
SizedBox(
height: 4,
),
Text(
event.advise ?? '',
style: Theme.of(context)
.textTheme
.body1
.copyWith(fontSize: 12),
)
]
: [],
],
),
),
),
],
),
);
}
build方法はちょっと長いですが、丸のコードが少ないです。
Padding(
padding: EdgeInsets.symmetric(horizontal: 22.0 - circleRadius),
child: Container(
width: circleRadius * 2,
height: circleRadius * 2,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: circleColor,
),
),
),
座標の計算は左縦線のx座標-リングの半径で得られます。これで簡単なtimelineを実現しました。ここでFutter時間軸Timelineの実現に関する記事を紹介します。Futter時間軸に関する詳細な内容は以前の文章を検索したり、下記の関連記事を見たりしてください。これからもよろしくお願いします。