Add API sample and docs for Expansible widget (#180273)

This PR adds an API example demonstrating how to use the Expansible
widget,
including programmatic control via ExpansibleController.

Changes included:
- Added a Material API example for Expansible
- Added a widget test for the API example
- Added documentation comments linking to the example

This addresses the request for improved Expansible documentation and
usage
examples.

Fixes #178698
This commit is contained in:
GowsikRaja 2026-01-12 23:24:38 +05:30 committed by GitHub
parent c8decadc7b
commit cccf0f1977
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 105 additions and 0 deletions

View File

@ -0,0 +1,75 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
/// Flutter code sample for [Expansible].
void main() => runApp(const ExpansibleApp());
/// An application that shows an example of how to use [Expansible].
class ExpansibleApp extends StatelessWidget {
const ExpansibleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Expansible Widget Example')),
body: const Center(child: ExpansibleWidgetExample()),
),
);
}
}
class ExpansibleWidgetExample extends StatefulWidget {
const ExpansibleWidgetExample({super.key});
@override
State<ExpansibleWidgetExample> createState() =>
_ExpansibleWidgetExampleState();
}
class _ExpansibleWidgetExampleState extends State<ExpansibleWidgetExample> {
final _controller = ExpansibleController();
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Expansible(
controller: _controller,
headerBuilder: (context, animation) => ListTile(
title: const Text('Tap to Expand'),
onTap: () {
if (_controller.isExpanded) {
_controller.collapse();
} else {
_controller.expand();
}
},
trailing: RotationTransition(
turns: Tween<double>(begin: 0.0, end: 0.5).animate(animation),
child: const Icon(Icons.arrow_drop_down),
),
),
bodyBuilder: (context, animation) => SizeTransition(
sizeFactor: animation,
child: const Text('Hidden content revealed!'),
),
expansibleBuilder: (context, header, body, animation) => Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [header, body],
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}

View File

@ -0,0 +1,23 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter_api_samples/material/expansible/expansible.0.dart'
as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Expansible can be expanded', (WidgetTester tester) async {
await tester.pumpWidget(const example.ExpansibleApp());
// Verify that the expanded content is not visible initially.
expect(find.text('Hidden content revealed!'), findsNothing);
// Tap the header to expand.
await tester.tap(find.text('Tap to Expand'));
await tester.pumpAndSettle();
// Verify that the expanded content is now visible.
expect(find.text('Hidden content revealed!'), findsOneWidget);
});
}

View File

@ -211,6 +211,13 @@ class ExpansibleController extends ChangeNotifier {
/// [ExpansibleController.collapse] as needed, most typically when the header
/// returned in [headerBuilder] is tapped.
///
///{@tool dartpad}
/// This example demonstrates how to use the [Expansible] widget and how an
/// [ExpansibleController] can be used to programmatically expand or collapse it.
///
/// ** See code in examples/api/lib/material/expansible/expansible.0.dart **
/// {@end-tool}
///
/// See also:
///
/// * [ExpansionTile], a Material-styled widget that expands and collapses.