Кто-нибудь знает, как добавить градиентный фон в CupertinoSliverAppBar?
Я пытаюсь добавить градиентный фон к CupertinoSliverAppBar
в приложении Flutter, но я не могу понять, как это сделать. SliverAppBar
имеет flexibleSpace
свойство, которое будет принимать градиент, кроме CupertinoSliverAppBar
только имеет backgroundColor
имущество.
В качестве альтернативы, если бы можно было переместить заголовок в flexibleSpace
больше слева, я мог бы пойти с этим. Но я не могу понять это тоже.
Я прочитал это:
И эта проблема открылась в репозитории Flutter: https://github.com/flutter/flutter/issues/25144
@rmtmckenzie делает свое дело! Стоит отметить, что это также работает с CupertinoSliverNavigationBar
, Кроме того, все анимации перехода сохраняются, за исключением того фона, для которого вы будете видеть backgroundColor
свойство является анимированным. Вы можете обмануть, используя один из цветов градиента в качестве backgroundColor
но это не идеально. Градиент действительно отображается ниже содержимого. Увидеть ниже:
2 ответа
Это на самом деле немного сложно - как вы упомянули, CupertinoSliverAppBar не поддерживает "FlexibleSpace" или что-то подобное, поэтому вы застряли на попытке использовать backgroundColor, который также не делает то, что вам нужно.
Я бы порекомендовал открыть выпуск репозитория Flutter, заявив, что это невозможно, и почему вы хотите это сделать. Они, вероятно, не сразу примут меры, но если они знают, что люди хотели бы сделать это, это может произойти.
Не вся надежда потеряна для немедленного исправления, хотя, мы можем обмануть! (хотя я надеюсь, что вы будете использовать менее уродливый градиент при написании своей версии)
То, что я сделал, это подкласс Border, а затем переопределил то, что он рисует, чтобы он рисовал градиент, который вы передаете перед рисованием фактической границы. Это работает, потому что он имеет контекст рисования, который покрывает всю панель приложения, и рисует на фоне панели приложения, но ниже его содержимого (надеюсь - он кажется ниже заголовка, по крайней мере, поэтому я предполагаю, что он также ниже всего остального). Цвет фона по-прежнему отображается под панелью приложения, поэтому, если ваш градиент несколько прозрачен, вы, вероятно, захотите установить backgroundColor в Colors.transparent.
Вот код:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() => runApp(GradientAppBar());
class GradientCheatingBorder extends Border {
const GradientCheatingBorder({
this.gradient,
BorderSide top = BorderSide.none,
BorderSide right = BorderSide.none,
BorderSide bottom = BorderSide.none,
BorderSide left = BorderSide.none,
}) : super(top: top, right: right, bottom: bottom, left: left);
const GradientCheatingBorder.fromBorderSide(BorderSide side, {this.gradient})
: super.fromBorderSide(side);
factory GradientCheatingBorder.all({
Color color = const Color(0xFF000000),
double width = 1.0,
BorderStyle style = BorderStyle.solid,
Gradient gradient,
}) {
final BorderSide side =
BorderSide(color: color, width: width, style: style);
return GradientCheatingBorder.fromBorderSide(side, gradient: gradient);
}
final Gradient gradient;
@override
void paint(
Canvas canvas,
Rect rect, {
TextDirection textDirection,
BoxShape shape = BoxShape.rectangle,
BorderRadius borderRadius,
}) {
if (gradient != null) {
canvas.drawRect(
rect,
Paint()
..shader = gradient.createShader(rect)
..style = PaintingStyle.fill,
);
}
super.paint(
canvas,
rect,
textDirection: textDirection,
shape: shape,
borderRadius: borderRadius,
);
}
}
class GradientAppBar extends StatefulWidget {
@override
_GradientAppBarState createState() => _GradientAppBarState();
}
class _GradientAppBarState extends State<GradientAppBar> {
@override
Widget build(BuildContext context) {
return CupertinoApp(
home: CustomScrollView(
slivers: <Widget>[
CupertinoSliverNavigationBar(
largeTitle: Text("Title"),
border: GradientCheatingBorder.fromBorderSide(
BorderSide.none,
gradient: LinearGradient(colors: [Colors.black, Colors.white]),
),
),
SliverList(
delegate: SliverChildListDelegate(
[
Container(
color: Colors.blue,
height: 500,
),
Divider(),
Container(
color: Colors.black12,
height: 500,
),
Divider(),
Container(
color: Colors.lightBlue,
height: 500,
),
Divider(),
Container(
color: Colors.lightGreen,
height: 500,
),
Divider(),
],
),
),
],
),
);
}
}
ты можешь попробовать это
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Colors.red,
Colors.blue
],
),
),
),