如何实现位置:Flutter的粘滞和底部0? [英] How to implement position: sticky and bottom 0 with Flutter?

查看:58
本文介绍了如何实现位置:Flutter的粘滞和底部0?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用粘性页脚构建列表视图,例如

在CSS中,

  .main-footer {位置:粘性;底部:0;} 

但是如何处理Flutter?

我想要的

  1. 可滚动的大内容
  2. 脚(粘性)
  3. 可滚动的大内容

1和2首先显示(可滚动内容和固定页脚).滚动到1的末尾后,页脚(2)变得不固定.其余内容(3)将显示在页脚(2)下方.

我尝试使用

代码

  import'dart:math';导入'package:flutter/material.dart';导入'package:flutter/rendering.dart';void main()=>runApp(MyApp());MyApp类扩展了StatelessWidget {//此小部件是您的应用程序的根.@override窗口小部件build(BuildContext context){返回MaterialApp(标题:固定页脚",主题:ThemeData(primarySwatch:Colors.blue,),家:脚手架(正文:_FixedFooterDemo(),floatActionButton:FloatingActionButton(onPressed:(){},子级:Icon(Icons.add),),),);}}_FixedFooterDemo类扩展了StatelessWidget {const _FixedFooterDemo({关键}):super(key:key);@override窗口小部件build(BuildContext context){返回CustomScrollView(条子:< Widget> [SliverAppBar(标题:文本(固定页脚"),),SliverList(委托人:SliverChildListDelegate(List.generate(20,_buildListItem)),),SliverStickyFooter(孩子:中心(子代:RaisedButton(onPressed:(){},子级:文本(固定在列表按钮下"),),),),SliverFillRemaining(子代:集装箱(颜色:Colors.yellow,孩子:中心(子级:Text('below space'),),),),],);}ListTile _buildListItem(int i){返回ListTile(标题:文字("$ i"项,),字幕:文字(坐在ipsum上就坐下来吧.最低限度的工作量dolore velit sint fugiat.慢性牙周炎患者最小阿利基普·尼西·雷普兰德特·乌拉姆科·杜伊斯·莫利特.不可替代的动物Eu officia dolore deserunt do est cupidatat duis elit.玛格丽特(Pariatur magna)再次表达了自己的不义之物(Lorem sunt aute).',maxLines:2),);}}SliverStickyFooter类扩展SingleChildRenderObjectWidget {const SliverStickyFooter({关键小部件子代,}):super(key:key,child:child);@overrideRenderSliv​​erStickyFooter createRenderObject(BuildContext context)=>RenderSliv​​erStickyFooter();}RenderSliv​​erStickyFooter类扩展了RenderSliv​​erSingleBoxAdapter {///创建一个[RenderSliv​​er]并包装一个[RenderBox],该[RenderBox]的大小适合///视口中的剩余空间.RenderSliv​​erStickyFooter({RenderBox子级,}):super(child:child);@overridevoid performLayout(){孩子?.layout(Constraints.asBoxConstraints(),parentUsesSize:true,);最终paintedChildSize =computePaintOffset(constraints,from:0.0,to:child.size.height);断言(paintedChildSize.isFinite);assert(paintedChildSize> = 0.0);几何= SliverGeometry(scrollExtent:child.size.height,paintExtent:paintedChildSize,maxPaintExtent:paintedChildSize,hasVisualOverflow:是的,paintOrigin:-child.size.height + paintedChildSize,可见:正确,);if(child!= null){setChildParentData(child,约束,几何);}}} 

解决方案

尝试一下

  import'package:flutter/material.dart';类Sticky扩展了StatefulWidget {置顶({Key key}):super(key:key);_StickyState createState()=>_StickyState();}类_StickyState扩展了State< Sticky>{@override窗口小部件build(BuildContext context){返回SafeArea(孩子:脚手架(身体:堆栈(子代:< Widget> [定位(子代:集装箱(颜色:Colors.black38,高度:60,宽度:MediaQuery.of(context).size.width,子级:Text('Header'),),上:0,),定位(子代:集装箱(子级:Text('Content'),),最高:60),定位(子代:集装箱(颜色:Colors.black38,高度:60,宽度:MediaQuery.of(context).size.width,子代:Text('Footer'),),底部:0,),],),),);}} 

I want to build a list view with sticky footer like this article's "Stick to the bottom?!" in Flutter.

In CSS,

.main-footer{     
     position: sticky; 
     bottom: 0;
}

but how to do with Flutter?

What I want

  1. Scrollable large content
  2. Footer (sticky)
  3. Scrollable large content

1 and 2 are visible at First (Scrollable content and fixed footer). After scroll to end of 1, Footer (2) become not fixed. Rest of contents (3) will be shown below footer(2).

I tried to implement above with CustomScrollView but footer button is not drawn above list.

code

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Fixed footer',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        body: _FixedFooterDemo(),
        floatingActionButton: FloatingActionButton(
          onPressed: () {},
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return CustomScrollView(
      slivers: <Widget>[
        SliverAppBar(
          title: Text('Fixed footer'),
        ),
        SliverList(
          delegate: SliverChildListDelegate(List.generate(20, _buildListItem)),
        ),
        SliverStickyFooter(
          child: Center(
            child: RaisedButton(
              onPressed: () {},
              child: Text('Fixed under list button'),
            ),
          ),
        ),
        SliverFillRemaining(
          child: Container(
            color: Colors.yellow,
            child: Center(
              child: Text('below space'),
            ),
          ),
        ),
      ],
    );
  }

  ListTile _buildListItem(int i) {
    return ListTile(
      title: Text(
        'Item $i',
      ),
      subtitle: Text(
        'Sit est ipsum consequat sit ex. Minim magna laborum dolore aliqua sit dolore velit sint fugiat. Culpa officia tempor proident minim aliquip nisi reprehenderit ullamco duis mollit. Aute velit irure ut Lorem pariatur anim mollit cillum dolor irure quis. Eu officia dolore deserunt do est cupidatat duis elit. Pariatur magna reprehenderit aliquip ea irure Lorem sunt aute.',
        maxLines: 2,
      ),
    );
  }
}

class SliverStickyFooter extends SingleChildRenderObjectWidget {
  const SliverStickyFooter({
    Key key,
    Widget child,
  }) : super(key: key, child: child);

  @override
  RenderSliverStickyFooter createRenderObject(BuildContext context) =>
      RenderSliverStickyFooter();
}

class RenderSliverStickyFooter extends RenderSliverSingleBoxAdapter {
  /// Creates a [RenderSliver] that wraps a [RenderBox] which is sized to fit
  /// the remaining space in the viewport.
  RenderSliverStickyFooter({
    RenderBox child,
  }) : super(child: child);

  @override
  void performLayout() {
    child?.layout(
      constraints.asBoxConstraints(),
      parentUsesSize: true,
    );

    final paintedChildSize =
        calculatePaintOffset(constraints, from: 0.0, to: child.size.height);
    assert(paintedChildSize.isFinite);
    assert(paintedChildSize >= 0.0);
    geometry = SliverGeometry(
      scrollExtent: child.size.height,
      paintExtent: paintedChildSize,
      maxPaintExtent: paintedChildSize,
      hasVisualOverflow: true,
      paintOrigin: -child.size.height + paintedChildSize,
      visible: true,
    );

    if (child != null) {
      setChildParentData(child, constraints, geometry);
    }
  }
}

解决方案

Try this

import 'package:flutter/material.dart';

class Sticky extends StatefulWidget {
  Sticky({Key key}) : super(key: key);

  _StickyState createState() => _StickyState();
}

class _StickyState extends State<Sticky> {
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: Stack(
          children: <Widget>[
            Positioned(
              child: Container(
                color: Colors.black38,
                height: 60,
                width: MediaQuery.of(context).size.width,
                child: Text('Header'),
              ),
              top: 0,
            ),
            Positioned(
              child: Container(
                child: Text('Content'),
              ),
              top: 60,
            ),
            Positioned(
              child: Container(
                color: Colors.black38,
                height: 60,
                width: MediaQuery.of(context).size.width,
                child: Text('Footer'),
              ),
              bottom: 0,
            ),
          ],
        ),
      ),
    );
  }
}

这篇关于如何实现位置:Flutter的粘滞和底部0?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆