Files
rive-flutter/example/lib/examples/rive_panel.dart
HayesGordon ce00421de5 feat(flutter): add shared texture through rive panel (#10451) 7359e8b824
* feat(flutter): add shared texture through rive panel

* feat: updates to rive panel

* chore: revert pub path change

* docs: update api level docs

* feat: expose drawOrder

feat: Add fallback AtlasTypes that don't need float color buffers (#10475) 5e6f683b9e
Floating point color buffers are only supported via extensions in GL.
Previously, the feather atlas would just break when this functionality
wasn't present.

This PR adds support for multiple different AtlasTypes that make use of
various GL extensions to render the atlas. As a final resort, if none of
the other extensions are available, it can split coverage up into rgba8
compoments. This mode works on unextended GL at the cost of quality.

Co-authored-by: Gordon <pggordonhayes@gmail.com>
2025-09-03 17:20:33 +00:00

169 lines
3.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:rive/rive.dart';
class ExampleRivePanel extends StatelessWidget {
const ExampleRivePanel({super.key});
@override
Widget build(BuildContext context) {
return const RivePanel(
child: ListViewExample(),
);
}
}
class RowExample extends StatefulWidget {
const RowExample({super.key});
@override
State<RowExample> createState() => _RowExampleState();
}
class _RowExampleState extends State<RowExample> {
// Only useful when using `Factory.rive`. `Factory.flutter` draws to a single
// render target already.
final factory = Factory.rive;
late List<FileLoader> listOfFileLoaders = [
FileLoader.fromAsset(
'assets/rating.riv',
riveFactory: factory,
),
FileLoader.fromAsset(
'assets/vehicles.riv',
riveFactory: factory,
),
FileLoader.fromAsset(
'assets/perf/rivs/travel_icons.riv',
riveFactory: factory,
),
FileLoader.fromAsset(
'assets/coyote.riv',
riveFactory: factory,
),
FileLoader.fromAsset(
'assets/perf/rivs/Tom_Morello_2.riv',
riveFactory: factory,
),
FileLoader.fromAsset(
'assets/perf/rivs/towersDemo.riv',
riveFactory: factory,
),
FileLoader.fromAsset(
'assets/perf/rivs/walking.riv',
riveFactory: factory,
),
FileLoader.fromAsset(
'assets/perf/rivs/skull_404.riv',
riveFactory: factory,
),
FileLoader.fromAsset(
'assets/perf/rivs/adventuretime_marceline_pb.riv',
riveFactory: factory,
),
FileLoader.fromAsset(
'assets/perf/rivs/Zombie_Character.riv',
riveFactory: factory,
),
];
@override
void dispose() {
for (var fileLoader in listOfFileLoaders) {
fileLoader.dispose();
}
super.dispose();
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 50.0),
child: SingleChildScrollView(
child: Wrap(
children: [
...listOfFileLoaders
.map((fileLoader) => SizedSample(fileLoader: fileLoader)),
],
),
),
);
}
}
class SizedSample extends StatelessWidget {
const SizedSample({super.key, required this.fileLoader});
final FileLoader fileLoader;
@override
Widget build(BuildContext context) {
return SizedBox(
width: 200,
height: 200,
child: MyRiveWidget(fileLoader: fileLoader),
);
}
}
class ListViewExample extends StatefulWidget {
const ListViewExample({super.key});
@override
State<ListViewExample> createState() => _ListViewExampleState();
}
class _ListViewExampleState extends State<ListViewExample> {
late final fileLoader = FileLoader.fromAsset(
'assets/rating.riv',
riveFactory: Factory.rive,
);
@override
void dispose() {
fileLoader.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: 10,
itemBuilder: (context, index) {
return SizedBox(
width: 500,
height: 100,
child: MyRiveWidget(fileLoader: fileLoader),
);
},
);
}
}
class MyRiveWidget extends StatelessWidget {
const MyRiveWidget({super.key, required this.fileLoader});
final FileLoader fileLoader;
@override
Widget build(BuildContext context) {
return RiveWidgetBuilder(
fileLoader: fileLoader,
builder: (context, state) => switch (state) {
RiveLoading() => const Center(
child: Center(child: CircularProgressIndicator()),
),
RiveFailed() => ErrorWidget.withDetails(
message: state.error.toString(),
error: FlutterError(state.error.toString()),
),
RiveLoaded() => RiveWidget(
controller: state.controller,
fit: Fit.contain,
/// Set this to true to draw to the nearest `RivePanel`
useSharedTexture: true,
)
},
);
}
}