mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
179 lines
6.0 KiB
Dart
179 lines
6.0 KiB
Dart
// 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/cupertino.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
import 'input_decorator.dart';
|
|
import 'menu_style.dart';
|
|
import 'theme.dart';
|
|
|
|
// Examples can assume:
|
|
// late BuildContext context;
|
|
|
|
/// Overrides the default values of visual properties for descendant [DropdownMenu] widgets.
|
|
///
|
|
/// Descendant widgets obtain the current [DropdownMenuThemeData] object with
|
|
/// [DropdownMenuTheme.of]. Instances of [DropdownMenuTheme] can
|
|
/// be customized with [DropdownMenuThemeData.copyWith].
|
|
///
|
|
/// Typically a [DropdownMenuTheme] is specified as part of the overall [Theme] with
|
|
/// [ThemeData.dropdownMenuTheme].
|
|
///
|
|
/// All [DropdownMenuThemeData] properties are null by default. When null, the [DropdownMenu]
|
|
/// computes its own default values, typically based on the overall
|
|
/// theme's [ThemeData.colorScheme], [ThemeData.textTheme], and [ThemeData.iconTheme].
|
|
@immutable
|
|
class DropdownMenuThemeData with Diagnosticable {
|
|
/// Creates a [DropdownMenuThemeData] that can be used to override default properties
|
|
/// in a [DropdownMenuTheme] widget.
|
|
const DropdownMenuThemeData({
|
|
this.textStyle,
|
|
this.inputDecorationTheme,
|
|
this.menuStyle,
|
|
});
|
|
|
|
/// Overrides the default value for [DropdownMenu.textStyle].
|
|
final TextStyle? textStyle;
|
|
|
|
/// The input decoration theme for the [TextField]s in a [DropdownMenu].
|
|
///
|
|
/// If this is null, the [DropdownMenu] provides its own defaults.
|
|
final InputDecorationTheme? inputDecorationTheme;
|
|
|
|
/// Overrides the menu's default style in a [DropdownMenu].
|
|
///
|
|
/// Any values not set in the [MenuStyle] will use the menu default for that
|
|
/// property.
|
|
final MenuStyle? menuStyle;
|
|
|
|
/// Creates a copy of this object with the given fields replaced with the
|
|
/// new values.
|
|
DropdownMenuThemeData copyWith({
|
|
TextStyle? textStyle,
|
|
InputDecorationTheme? inputDecorationTheme,
|
|
MenuStyle? menuStyle,
|
|
}) {
|
|
return DropdownMenuThemeData(
|
|
textStyle: textStyle ?? this.textStyle,
|
|
inputDecorationTheme: inputDecorationTheme ?? this.inputDecorationTheme,
|
|
menuStyle: menuStyle ?? this.menuStyle,
|
|
);
|
|
}
|
|
|
|
/// Linearly interpolates between two dropdown menu themes.
|
|
static DropdownMenuThemeData lerp(DropdownMenuThemeData? a, DropdownMenuThemeData? b, double t) {
|
|
if (identical(a, b) && a != null) {
|
|
return a;
|
|
}
|
|
return DropdownMenuThemeData(
|
|
textStyle: TextStyle.lerp(a?.textStyle, b?.textStyle, t),
|
|
inputDecorationTheme: t < 0.5 ? a?.inputDecorationTheme : b?.inputDecorationTheme,
|
|
menuStyle: MenuStyle.lerp(a?.menuStyle, b?.menuStyle, t),
|
|
);
|
|
}
|
|
|
|
@override
|
|
int get hashCode => Object.hash(
|
|
textStyle,
|
|
inputDecorationTheme,
|
|
menuStyle,
|
|
);
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
if (identical(this, other)) {
|
|
return true;
|
|
}
|
|
if (other.runtimeType != runtimeType) {
|
|
return false;
|
|
}
|
|
return other is DropdownMenuThemeData
|
|
&& other.textStyle == textStyle
|
|
&& other.inputDecorationTheme == inputDecorationTheme
|
|
&& other.menuStyle == menuStyle;
|
|
}
|
|
|
|
@override
|
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
|
super.debugFillProperties(properties);
|
|
properties.add(DiagnosticsProperty<TextStyle>('textStyle', textStyle, defaultValue: null));
|
|
properties.add(DiagnosticsProperty<InputDecorationTheme>('inputDecorationTheme', inputDecorationTheme, defaultValue: null));
|
|
properties.add(DiagnosticsProperty<MenuStyle>('menuStyle', menuStyle, defaultValue: null));
|
|
}
|
|
}
|
|
|
|
/// An inherited widget that defines the visual properties for [DropdownMenu]s in this widget's subtree.
|
|
///
|
|
/// Values specified here are used for [DropdownMenu] properties that are not
|
|
/// given an explicit non-null value.
|
|
class DropdownMenuTheme extends InheritedTheme {
|
|
/// Creates a [DropdownMenuTheme] that controls visual parameters for
|
|
/// descendant [DropdownMenu]s.
|
|
const DropdownMenuTheme({
|
|
super.key,
|
|
required this.data,
|
|
required super.child,
|
|
});
|
|
|
|
/// Specifies the visual properties used by descendant [DropdownMenu]
|
|
/// widgets.
|
|
final DropdownMenuThemeData data;
|
|
|
|
/// The closest instance of this class that encloses the given context.
|
|
///
|
|
/// If there is no enclosing [DropdownMenuTheme] widget, then
|
|
/// [ThemeData.dropdownMenuTheme] is used.
|
|
///
|
|
/// Typical usage is as follows:
|
|
///
|
|
/// ```dart
|
|
/// DropdownMenuThemeData theme = DropdownMenuTheme.of(context);
|
|
/// ```
|
|
///
|
|
/// See also:
|
|
///
|
|
/// * [maybeOf], which returns null if it doesn't find a
|
|
/// [DropdownMenuTheme] ancestor.
|
|
static DropdownMenuThemeData of(BuildContext context) {
|
|
return maybeOf(context) ?? Theme.of(context).dropdownMenuTheme;
|
|
}
|
|
|
|
/// The data from the closest instance of this class that encloses the given
|
|
/// context, if any.
|
|
///
|
|
/// Use this function if you want to allow situations where no
|
|
/// [DropdownMenuTheme] is in scope. Prefer using [DropdownMenuTheme.of]
|
|
/// in situations where a [DropdownMenuThemeData] is expected to be
|
|
/// non-null.
|
|
///
|
|
/// If there is no [DropdownMenuTheme] in scope, then this function will
|
|
/// return null.
|
|
///
|
|
/// Typical usage is as follows:
|
|
///
|
|
/// ```dart
|
|
/// DropdownMenuThemeData? theme = DropdownMenuTheme.maybeOf(context);
|
|
/// if (theme == null) {
|
|
/// // Do something else instead.
|
|
/// }
|
|
/// ```
|
|
///
|
|
/// See also:
|
|
///
|
|
/// * [of], which will return [ThemeData.dropdownMenuTheme] if it doesn't
|
|
/// find a [DropdownMenuTheme] ancestor, instead of returning null.
|
|
static DropdownMenuThemeData? maybeOf(BuildContext context) {
|
|
return context.dependOnInheritedWidgetOfExactType<DropdownMenuTheme>()?.data;
|
|
}
|
|
|
|
@override
|
|
Widget wrap(BuildContext context, Widget child) {
|
|
return DropdownMenuTheme(data: data, child: child);
|
|
}
|
|
|
|
@override
|
|
bool updateShouldNotify(DropdownMenuTheme oldWidget) => data != oldWidget.data;
|
|
}
|