Files
rive-flutter/example/lib/examples/databinding_artboards.dart
HayesGordon 16b484c81c chore(flutter): release with rive_native bump and update examples (#10190) eec2f66855
* chore(flutter): bump rive_native

* chore(flutter): add examples

* docs: update changelog

fix: recursively check whether an artboard is its ancestor before usi… (#10184) 53fb2577bc
* fix: recursively check whether an artboard is its ancestor before using it as the source of a nested artboard

fix(wagyu): proper init of Wagyu Render Pass Inputs (#10175) ff8fc66bc4
* proper init of Wagyu Render Pass Inputs

* fixed build issues

* clang-format

* proper black clear color

chore: update thumbnailer for new rive building set-up 9fd4961e9b

Co-authored-by: Gordon <pggordonhayes@gmail.com>
2025-07-16 17:53:55 +00:00

170 lines
4.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:rive/rive.dart';
import 'package:rive_example/main.dart' show RiveExampleApp;
/// Example using Rive data binding artboards at runtime.
///
/// See: https://rive.app/docs/runtimes/data-binding
class ExampleDataBindingArtboards extends StatefulWidget {
const ExampleDataBindingArtboards({super.key});
@override
State<ExampleDataBindingArtboards> createState() =>
_ExampleDataBindingArtboardsState();
}
class _ExampleDataBindingArtboardsState
extends State<ExampleDataBindingArtboards> {
late final File travelPackFile;
late final File webPackFile;
late final RiveWidgetController controller;
late final ViewModelInstance viewModelInstance;
late ViewModelInstanceArtboard iconProperty;
late BindableArtboard bindableArtboard;
bool isInitialized = false;
// Available artboard options
final List<String> travelPackOptions = [
'map',
'car',
'gas',
'compass',
'walk',
'food',
'GPS',
'coffee'
];
final List<String> webPackOptions = [
'download',
'refresh',
'lock',
'wifi',
'email',
'www'
];
String selectedTravelPackArtboard = 'map';
String selectedWebPackArtboard = 'download';
@override
void initState() {
super.initState();
initRive();
}
void initRive() async {
travelPackFile = (await File.asset(
'assets/travel_icons_pack.riv',
riveFactory: RiveExampleApp.getCurrentFactory,
))!;
webPackFile = (await File.asset(
'assets/web_icons_pack.riv',
riveFactory: RiveExampleApp.getCurrentFactory,
))!;
controller =
RiveWidgetController(travelPackFile); // uses default artboard: "Demo"
viewModelInstance = controller.dataBind(DataBind.auto());
iconProperty = viewModelInstance.artboard('icon')!;
bindableArtboard =
travelPackFile.artboardToBind(selectedTravelPackArtboard)!;
iconProperty.value = bindableArtboard;
setState(() => isInitialized = true);
}
void _onTravelIconSelected(String? newValue) {
if (newValue != null && newValue != selectedTravelPackArtboard) {
setState(() {
selectedTravelPackArtboard = newValue;
bindableArtboard = travelPackFile.artboardToBind(newValue)!;
iconProperty.value = bindableArtboard;
});
}
}
void _onWebPackIconSelected(String? newValue) {
if (newValue != null && newValue != selectedWebPackArtboard) {
setState(() {
selectedWebPackArtboard = newValue;
bindableArtboard = webPackFile.artboardToBind(newValue)!;
iconProperty.value = bindableArtboard;
});
}
}
@override
void dispose() {
travelPackFile.dispose();
webPackFile.dispose();
bindableArtboard.dispose();
controller.dispose();
viewModelInstance.dispose();
iconProperty.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
if (!isInitialized) {
return const Center(child: CircularProgressIndicator());
}
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Wrap(
children: [
_buildDropdown(
'Travel Pack',
travelPackOptions,
selectedTravelPackArtboard,
_onTravelIconSelected,
),
_buildDropdown(
'Web Pack',
webPackOptions,
selectedWebPackArtboard,
_onWebPackIconSelected,
),
],
),
Expanded(
child: RiveWidget(controller: controller),
),
],
);
}
Widget _buildDropdown(String title, List<String> options, String selected,
Function(String?) onChanged) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(title),
Padding(
padding: const EdgeInsets.all(16.0),
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(4.0),
),
child: DropdownButton<String>(
value: selected,
items: options.map((String artboard) {
return DropdownMenuItem<String>(
value: artboard,
child: Text(artboard),
);
}).toList(),
onChanged: (newValue) => onChanged(newValue),
underline: Container(),
hint: const Text('Select Artboard'),
),
),
),
],
),
);
}
}