title_bar_widget.dart 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import 'package:flutter/material.dart';
  2. import 'package:photos/theme/ente_theme.dart';
  3. class TitleBarWidget extends StatelessWidget {
  4. final String? title;
  5. final String? caption;
  6. final Widget? flexibleSpaceTitle;
  7. final String? flexibleSpaceCaption;
  8. //If passing IconButton, set visualDensity to -2 (horizontal & vertical).
  9. //This could be applicable to other widgets too. If layout looks different see if
  10. // VisualDensity property exists for the widget and try to find the right values.
  11. // https://api.flutter.dev/flutter/material/VisualDensity-class.html
  12. final List<Widget>? actionIcons;
  13. final bool isTitleBigWithoutLeading;
  14. const TitleBarWidget({
  15. this.title,
  16. this.caption,
  17. this.flexibleSpaceTitle,
  18. this.flexibleSpaceCaption,
  19. this.actionIcons,
  20. this.isTitleBigWithoutLeading = false,
  21. super.key,
  22. });
  23. @override
  24. Widget build(BuildContext context) {
  25. final textTheme = getEnteTextTheme(context);
  26. final colorTheme = getEnteColorScheme(context);
  27. return SliverAppBar(
  28. toolbarHeight: 48,
  29. leadingWidth: 48,
  30. automaticallyImplyLeading: false,
  31. pinned: true,
  32. expandedHeight: 102,
  33. centerTitle: false,
  34. titleSpacing: 0,
  35. title: Padding(
  36. padding: EdgeInsets.only(left: isTitleBigWithoutLeading ? 16 : 0),
  37. child: Column(
  38. crossAxisAlignment: CrossAxisAlignment.start,
  39. mainAxisAlignment: MainAxisAlignment.start,
  40. children: [
  41. title == null
  42. ? const SizedBox.shrink()
  43. : Text(
  44. title!,
  45. style: isTitleBigWithoutLeading
  46. ? textTheme.h2Bold
  47. : textTheme.largeBold,
  48. ),
  49. caption == null || isTitleBigWithoutLeading
  50. ? const SizedBox.shrink()
  51. : Text(
  52. caption!,
  53. style: textTheme.mini.copyWith(color: colorTheme.textMuted),
  54. )
  55. ],
  56. ),
  57. ),
  58. actions: [
  59. Padding(
  60. padding: const EdgeInsets.fromLTRB(4, 4, 12, 4),
  61. child: Row(
  62. children: _getActions(),
  63. ),
  64. ),
  65. ],
  66. leading: isTitleBigWithoutLeading
  67. ? null
  68. : Padding(
  69. padding: const EdgeInsets.all(4),
  70. child: IconButton(
  71. visualDensity:
  72. const VisualDensity(horizontal: -2, vertical: -2),
  73. onPressed: () {
  74. Navigator.pop(context);
  75. },
  76. icon: const Icon(Icons.arrow_back_outlined),
  77. ),
  78. ),
  79. flexibleSpace: FlexibleSpaceBar(
  80. background: Padding(
  81. padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
  82. child: Column(
  83. mainAxisAlignment: MainAxisAlignment.end,
  84. crossAxisAlignment: CrossAxisAlignment.start,
  85. mainAxisSize: MainAxisSize.min,
  86. children: <Widget>[
  87. flexibleSpaceTitle == null
  88. ? const SizedBox.shrink()
  89. : flexibleSpaceTitle!,
  90. flexibleSpaceCaption == null
  91. ? const SizedBox.shrink()
  92. : Text(
  93. flexibleSpaceCaption!,
  94. style: textTheme.small.copyWith(
  95. color: colorTheme.textMuted,
  96. ),
  97. overflow: TextOverflow.ellipsis,
  98. maxLines: 1,
  99. )
  100. ],
  101. ),
  102. ),
  103. ),
  104. );
  105. }
  106. _getActions() {
  107. if (actionIcons == null) {
  108. return <Widget>[const SizedBox.shrink()];
  109. }
  110. final actions = <Widget>[];
  111. bool addWhiteSpace = false;
  112. final length = actionIcons!.length;
  113. int index = 0;
  114. if (length == 0) {
  115. return <Widget>[const SizedBox.shrink()];
  116. }
  117. if (length == 1) {
  118. return actionIcons;
  119. }
  120. while (index < length) {
  121. if (!addWhiteSpace) {
  122. actions.add(actionIcons![index]);
  123. index++;
  124. addWhiteSpace = true;
  125. } else {
  126. actions.add(const SizedBox(width: 4));
  127. addWhiteSpace = false;
  128. }
  129. }
  130. return actions;
  131. }
  132. }