App高级感营造之 渐变色

178 阅读1分钟

效果

微信截图_20230531224513.png

3个案例:

  1. 带渐变色的AppBar
  2. 有立体感的Container
  3. 有层次感的叠放布局

源代码

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  
  AppBar _buildAppBar() {
    return AppBar(
      title: const Text(
        "渐变色AppBar",
        style: TextStyle(color: Colors.white),
      ),
      backgroundColor: Colors.transparent,
      flexibleSpace: _buildSimpleGradientContainer(),
    );
  }

  Widget _buildSimpleGradientContainer() {
    return Container(
      decoration: const BoxDecoration(
        gradient: LinearGradient(
            colors: [Colors.red, Colors.yellow],
            begin: Alignment.topLeft,
            end: Alignment.bottomRight,
            transform: GradientRotation(60)),
      ),
    );
  }

  Widget _gradient3DContainer() {
    return Container(
      margin: const EdgeInsets.all(40),
      padding: const EdgeInsets.all(20),
      decoration: BoxDecoration(
        gradient: LinearGradient(
          colors: [
            Colors.yellow[800]!,
            Colors.orange[700]!,
            Colors.pink[600]!,
            Colors.purple[500]!,
          ],
          begin: Alignment.topLeft,
          end: Alignment.bottomRight,
          transform: const GradientRotation(60),
        ),
        borderRadius: const BorderRadius.all(Radius.circular(10)),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withOpacity(0.2),
            spreadRadius: 3,
            blurRadius: 7,
            offset: const Offset(0, 3), // changes position of shadow
          ),
        ],
      ),
      child: const Center(
        child: Text(
          '渐变背景的Container',
          style: TextStyle(
            fontSize: 40,
            color: Colors.white,
            fontWeight: FontWeight.bold,
          ),
        ),
      ),
    );
  }

  Widget _buildBestContainer() {
    double w = 100;
    double h = 100;

    Widget buildSmall(double offSet, List<Color> colors, List<double> stops) {
      return Positioned(
        left: offSet,
        top: offSet,
        child: Container(
          height: w,
          width: h,
          decoration: BoxDecoration(
            gradient: LinearGradient(
              colors: colors,
              stops: stops,
              begin: Alignment.topCenter,
              end: Alignment.bottomCenter,
            ),
            borderRadius: BorderRadius.circular(20),
          ),
        ),
      );
    }

    List<Widget> buildList() {
      List<Widget> list = [];

      var s = [1, 2, 3, 4, 5, 6, 7];
      for (var element in s) {
        list.add(buildSmall(
          element * 10,
          [
            Colors.deepPurple.withOpacity(.5),
            Colors.purple.withOpacity(.8),
          ],
          const [0.5, 1],
        ));
      }

      return list;
    }

    return Stack(
      children: [
        const SizedBox(
          height: 300,
          width: 300,
        ),
        ...buildList()
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Colors.grey[300],
        appBar: _buildAppBar(),
        body: Center(
            child:
                Column(mainAxisAlignment: MainAxisAlignment.center, children: [
          _gradient3DContainer(),
          _buildBestContainer(),
        ])));
  }
}

实现原理

基本都是基于Container BoxDecoration LinearGradient。

支持的属性包括

属性名含义示例
colors颜色数组,定义渐变的每一种颜色[Colors.red, Colors.yellow]
stops颜色权重,定义每一种颜色的比例 与颜色数组的长度必须相同[0.5,1.0]
begin渐变开始的位置Alignment.topCenter
end渐变结束的位置,与begin共同定义渐变的方向Alignment.bottomCenter
transform可以对渲染出的渐变效果进行中心旋转GradientRotation(60)