blob: 3ce1708fa59b83805e8d3b8dda58f8e5aaa2ed28 [file] [log] [blame]
// 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 'dart:ui' show lerpDouble;
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'text_theme.dart';
import 'theme.dart';
/// Defines default property values for descendant [AppBar] widgets.
///
/// Descendant widgets obtain the current [AppBarTheme] object using
/// `AppBarTheme.of(context)`. Instances of [AppBarTheme] can be customized
/// with [AppBarTheme.copyWith].
///
/// Typically an [AppBarTheme] is specified as part of the overall [Theme] with
/// [ThemeData.appBarTheme].
///
/// All [AppBarTheme] properties are `null` by default. When null, the [AppBar]
/// will use the values from [ThemeData] if they exist, otherwise it will
/// provide its own defaults.
///
/// See also:
///
/// * [ThemeData], which describes the overall theme information for the
/// application.
@immutable
class AppBarTheme with Diagnosticable {
/// Creates a theme that can be used for [ThemeData.appBarTheme].
const AppBarTheme({
this.brightness,
this.color,
this.foregroundColor,
this.elevation,
this.shadowColor,
this.iconTheme,
this.actionsIconTheme,
this.textTheme,
this.centerTitle,
this.titleSpacing,
});
/// AppBar uses this value to determine the default (background) [color] and
/// [foregroundColor] as well as the app bar's [SystemUiOverlayStyle].
///
/// For [Brightness.dark], [SystemUiOverlayStyle.light] is used and for
/// [Brightness.light], [SystemUiOverlayStyle.dark] is used.
///
/// See also:
///
/// * [AppBar.brightness], which overrides the this value and the overall
/// theme's [ColorScheme.brightness].
/// * [Theme.of], which returns the current overall Material theme as
/// a [ThemeData].
/// * [ThemeData.colorScheme], the thirteen colors that most Material widget
/// default colors are based on.
/// * [ColorScheme.brightness], which indicates if the overall [Theme]
/// is light or dark.
final Brightness? brightness;
/// The app bar's background color.
///
/// If null, [AppBar] uses the overall theme's [ColorScheme.primary] if the
/// overall theme's brightness is [Brightness.light], and [ColorScheme.surface]
/// if the overall theme's [brightness] is [Brightness.dark].
///
/// See also:
///
/// * [AppBar.backgroundColor], which specifies the AppBar's background color
/// and overrides the background color defined by this theme.
/// * [foregroundColor], which specifies the color for icons and text within
/// the app bar.
/// * [Theme.of], which returns the current overall Material theme as
/// a [ThemeData].
/// * [ThemeData.colorScheme], the thirteen colors that most Material widget
/// default colors are based on.
/// * [ColorScheme.brightness], which indicates if the overall [Theme]
/// is light or dark.
final Color? color;
/// The default color for [Text] and [Icon]s within the app bar.
///
/// If null, [AppBar] uses the overall theme's [ColorScheme.onPrimary] if the
/// overall theme's brightness is [Brightness.light], and [ColorScheme.onSurface]
/// if the overall theme's [brightness] is [Brightness.dark].
///
/// This color is used to configure [DefaultTextStyle] and [IconTheme]
/// widgets.
///
/// See also:
///
/// * [AppBar.foregroundColor], which specifies the app bar's text and icon
/// colors and overrides the foreground color defined by this theme.
/// * [color], which specifies the app bar's background color.
/// * [Theme.of], which returns the current overall Material theme as
/// a [ThemeData].
/// * [ThemeData.colorScheme], the thirteen colors that most Material widget
/// default colors are based on.
/// * [ColorScheme.brightness], which indicates if the overall [Theme]
/// is light or dark.
final Color? foregroundColor;
/// Default value for [AppBar.elevation].
///
/// If null, [AppBar] uses a default value of 4.0.
final double? elevation;
/// Default value for [AppBar.shadowColor].
///
/// If null, [AppBar] uses a default value of fully opaque black.
final Color? shadowColor;
/// Default value for [AppBar.iconTheme].
///
/// If null, [AppBar] uses [ThemeData.primaryIconTheme].
final IconThemeData? iconTheme;
/// Default value for [AppBar.actionsIconTheme].
///
/// If null, [AppBar] uses [ThemeData.primaryIconTheme].
final IconThemeData? actionsIconTheme;
/// Default value for [AppBar.textTheme].
///
/// If null, [AppBar] uses [ThemeData.primaryTextTheme].
final TextTheme? textTheme;
/// Default value for [AppBar.centerTitle].
///
/// If null, the value is adapted to current [TargetPlatform].
final bool? centerTitle;
/// Default value for [AppBar.titleSpacing].
///
/// If null, [AppBar] uses default value of [NavigationToolbar.kMiddleSpacing].
final double? titleSpacing;
/// Creates a copy of this object with the given fields replaced with the
/// new values.
AppBarTheme copyWith({
IconThemeData? actionsIconTheme,
Brightness? brightness,
Color? color,
Color? foregroundColor,
double? elevation,
Color? shadowColor,
IconThemeData? iconTheme,
TextTheme? textTheme,
bool? centerTitle,
double? titleSpacing,
}) {
return AppBarTheme(
brightness: brightness ?? this.brightness,
color: color ?? this.color,
foregroundColor: foregroundColor ?? this.foregroundColor,
elevation: elevation ?? this.elevation,
shadowColor: shadowColor ?? this.shadowColor,
iconTheme: iconTheme ?? this.iconTheme,
actionsIconTheme: actionsIconTheme ?? this.actionsIconTheme,
textTheme: textTheme ?? this.textTheme,
centerTitle: centerTitle ?? this.centerTitle,
titleSpacing: titleSpacing ?? this.titleSpacing,
);
}
/// The [ThemeData.appBarTheme] property of the ambient [Theme].
static AppBarTheme of(BuildContext context) {
return Theme.of(context).appBarTheme;
}
/// Linearly interpolate between two AppBar themes.
///
/// The argument `t` must not be null.
///
/// {@macro dart.ui.shadow.lerp}
static AppBarTheme lerp(AppBarTheme? a, AppBarTheme? b, double t) {
assert(t != null);
return AppBarTheme(
brightness: t < 0.5 ? a?.brightness : b?.brightness,
color: Color.lerp(a?.color, b?.color, t),
foregroundColor: Color.lerp(a?.foregroundColor, b?.foregroundColor, t),
elevation: lerpDouble(a?.elevation, b?.elevation, t),
shadowColor: Color.lerp(a?.shadowColor, b?.shadowColor, t),
iconTheme: IconThemeData.lerp(a?.iconTheme, b?.iconTheme, t),
actionsIconTheme: IconThemeData.lerp(a?.actionsIconTheme, b?.actionsIconTheme, t),
textTheme: TextTheme.lerp(a?.textTheme, b?.textTheme, t),
centerTitle: t < 0.5 ? a?.centerTitle : b?.centerTitle,
titleSpacing: lerpDouble(a?.titleSpacing, b?.titleSpacing, t),
);
}
@override
int get hashCode {
return hashValues(
brightness,
color,
foregroundColor,
elevation,
shadowColor,
iconTheme,
actionsIconTheme,
textTheme,
centerTitle,
titleSpacing,
);
}
@override
bool operator ==(Object other) {
if (identical(this, other))
return true;
if (other.runtimeType != runtimeType)
return false;
return other is AppBarTheme
&& other.brightness == brightness
&& other.color == color
&& other.foregroundColor == foregroundColor
&& other.elevation == elevation
&& other.shadowColor == shadowColor
&& other.iconTheme == iconTheme
&& other.actionsIconTheme == actionsIconTheme
&& other.textTheme == textTheme
&& other.centerTitle == centerTitle
&& other.titleSpacing == titleSpacing;
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Brightness>('brightness', brightness, defaultValue: null));
properties.add(ColorProperty('color', color, defaultValue: null));
properties.add(ColorProperty('foregroundColor', foregroundColor, defaultValue: null));
properties.add(DiagnosticsProperty<double>('elevation', elevation, defaultValue: null));
properties.add(ColorProperty('shadowColor', shadowColor, defaultValue: null));
properties.add(DiagnosticsProperty<IconThemeData>('iconTheme', iconTheme, defaultValue: null));
properties.add(DiagnosticsProperty<IconThemeData>('actionsIconTheme', actionsIconTheme, defaultValue: null));
properties.add(DiagnosticsProperty<TextTheme>('textTheme', textTheme, defaultValue: null));
properties.add(DiagnosticsProperty<bool>('centerTitle', centerTitle, defaultValue: null));
properties.add(DiagnosticsProperty<double>('titleSpacing', titleSpacing, defaultValue: null));
}
}