Пользовательский виджет FlexibleSpaceBar - PullRequest
1 голос
/ 03 августа 2020

Я хочу, чтобы заголовок находился под изображением, а также был свернут вместе с изображением ......

Чего я добился

enter image description here

home: Scaffold(
  body: CustomScrollView(
    slivers: [
      SliverAppBar(

       expandedHeight: 220.0,
        floating: true,
        pinned: true,
        snap: true,
        elevation: 50,
        backgroundColor: Colors.pink,
        flexibleSpace: FlexibleSpaceBar(
            centerTitle: true,
            title: Text('Title',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 16.0,
                )),
            background: Image.network(
              'https://images.pexels.com/photos/443356/pexels-photo-443356.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
              fit: BoxFit.cover,
            )
        ),
      ),
      new SliverList(
          delegate: new SliverChildListDelegate(_buildList(50))
      ),
    ],
  ),

what I want

введите описание изображения здесь

Спасибо за помощь

1 Ответ

1 голос
/ 14 августа 2020

Надеюсь, я не опоздал, и мой ответ будет вам полезен.

enter image description here

If you check the flexibleSpace parameter type, you notice that it takes any Widget.

So you can create your own widget, and move title from SliverAppBar to your NewFlexibleSpaceWidget.

Plus you can go and check FlexibleSpaceBar , чтобы увидеть, как команда разработчиков flutter реализует это.

Когда мы сжимаем или расширяем SliverAppBarWidget, он изменяет BoxConstraints из FlexibleSpace, так что это означает, что мы можем поймать новую высоту, используя LayoutBuilder, что даст нам текущий BoxConstraints. И мы можем использовать их для рисования анимации.

введите описание изображения здесь

import 'dart:math' as math;

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        body: SafeArea(
          child: MyHomePage(),
        ),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  ScrollController controller = ScrollController();
  @override
  Widget build(BuildContext context) {
    return CustomScrollView(
      physics: ClampingScrollPhysics(),
      controller: controller,
      slivers: [
        SliverAppBar(
          expandedHeight: 220.0,
          floating: true,
          pinned: true,
          snap: true,
          elevation: 50,
          backgroundColor: Colors.pink,
          leading: IconButton(
            icon: Icon(Icons.filter_1),
            onPressed: () {},
          ),
          flexibleSpace: _MyAppSpace(),
        ),
        SliverList(
          delegate: SliverChildListDelegate(
            List.generate(
              200,
              (index) => Card(
                child: Padding(
                  padding: EdgeInsets.all(10),
                  child: Text('text $index'),
                ),
              ),
            ),
          ),
        )
      ],
    );
  }
}

class _MyAppSpace extends StatelessWidget {
  const _MyAppSpace({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, c) {
        final settings = context
            .dependOnInheritedWidgetOfExactType<FlexibleSpaceBarSettings>();
        final deltaExtent = settings.maxExtent - settings.minExtent;
        final t =
            (1.0 - (settings.currentExtent - settings.minExtent) / deltaExtent)
                .clamp(0.0, 1.0) as double;
        final fadeStart = math.max(0.0, 1.0 - kToolbarHeight / deltaExtent);
        const fadeEnd = 1.0;
        final opacity = 1.0 - Interval(fadeStart, fadeEnd).transform(t);

        return Opacity(
          opacity: opacity,
          child: Column(
            children: [
              Flexible(
                child: Container(
                  width: double.infinity,
                  child: Image.network(
                    'https://images.pexels.com/photos/443356/pexels-photo-443356.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
                    fit: BoxFit.cover,
                  ),
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Text(
                  'Title',
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 26.0,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ),
            ],
          ),
        );
      },
    );
  }
}
...