1// Copyright 2014 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'dart:ui';
6
7import 'package:flutter/material.dart';
8
9/// Flutter code sample for [ReorderableListView].
10
11void main() => runApp(const ReorderableApp());
12
13class ReorderableApp extends StatelessWidget {
14 const ReorderableApp({super.key});
15
16 @override
17 Widget build(BuildContext context) {
18 return MaterialApp(
19 home: Scaffold(
20 appBar: AppBar(title: const Text('ReorderableListView Sample')),
21 body: const ReorderableExample(),
22 ),
23 );
24 }
25}
26
27class ReorderableExample extends StatefulWidget {
28 const ReorderableExample({super.key});
29
30 @override
31 State<ReorderableExample> createState() => _ReorderableExampleState();
32}
33
34class _ReorderableExampleState extends State<ReorderableExample> {
35 final List<int> _items = List<int>.generate(50, (int index) => index);
36
37 @override
38 Widget build(BuildContext context) {
39 final Color oddItemColor = Colors.lime.shade100;
40 final Color evenItemColor = Colors.deepPurple.shade100;
41
42 final List<Card> cards = <Card>[
43 for (int index = 0; index < _items.length; index += 1)
44 Card(
45 key: Key('$index'),
46 color: _items[index].isOdd ? oddItemColor : evenItemColor,
47 child: SizedBox(height: 80, child: Center(child: Text('Card ${_items[index]}'))),
48 ),
49 ];
50
51 Widget proxyDecorator(Widget child, int index, Animation<double> animation) {
52 return AnimatedBuilder(
53 animation: animation,
54 builder: (BuildContext context, Widget? child) {
55 final double animValue = Curves.easeInOut.transform(animation.value);
56 final double elevation = lerpDouble(1, 6, animValue)!;
57 final double scale = lerpDouble(1, 1.02, animValue)!;
58 return Transform.scale(
59 scale: scale,
60 // Create a Card based on the color and the content of the dragged one
61 // and set its elevation to the animated value.
62 child: Card(elevation: elevation, color: cards[index].color, child: cards[index].child),
63 );
64 },
65 child: child,
66 );
67 }
68
69 return ReorderableListView(
70 padding: const EdgeInsets.symmetric(horizontal: 40),
71 proxyDecorator: proxyDecorator,
72 onReorder: (int oldIndex, int newIndex) {
73 setState(() {
74 if (oldIndex < newIndex) {
75 newIndex -= 1;
76 }
77 final int item = _items.removeAt(oldIndex);
78 _items.insert(newIndex, item);
79 });
80 },
81 children: cards,
82 );
83 }
84}
85