簡體   English   中英

如何在 flutter 中堆疊彼此重疊的小部件

[英]How do I stack widgets overlapping each other in flutter

我需要像這樣堆疊小部件:

硬幣

我寫了下面的代碼。 然而,硬幣接連出現,帶有一些默認填充。 我怎樣才能得到像上圖這樣的東西?

Row(
  children: <Widget>[
    Icon(
      Icons.monetization_on, size: 36.0, 
      color: const Color.fromRGBO(218, 165, 32, 1.0),
    ),
    Icon(
      Icons.monetization_on, size: 36.0,
      color: const Color.fromRGBO(218, 165, 32, 1.0),
    ),
  ],
),

您可以使用帶有PositionedStack來實現此目的:

在此處輸入圖片說明

class StackExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(),
      body:  new Container(
        padding: const EdgeInsets.all(8.0),
          height: 500.0,
          width: 500.0,
          // alignment: FractionalOffset.center,
          child: new Stack(
            //alignment:new Alignment(x, y)
            children: <Widget>[
              new Icon(Icons.monetization_on, size: 36.0, color: const Color.fromRGBO(218, 165, 32, 1.0)),
              new Positioned(
                left: 20.0,
                child: new Icon(Icons.monetization_on, size: 36.0, color: const Color.fromRGBO(218, 165, 32, 1.0)),
              ),
              new Positioned(
                left:40.0,
                child: new Icon(Icons.monetization_on, size: 36.0, color: const Color.fromRGBO(218, 165, 32, 1.0)),
              )

            ],
          ),
        ),
      )
    ;
  }
}

這就是你如何得到一些漂亮的陰影,使圖標更加突出:

在此處輸入圖片說明

class StackExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(),
      body:  new Container(
        padding: const EdgeInsets.all(8.0),
          height: 500.0,
          width: 500.0,
          // alignment: FractionalOffset.center,
          child: new Stack(
            //alignment:new Alignment(x, y)
            children: <Widget>[
              new Container(
                decoration: new BoxDecoration(
                  borderRadius: BorderRadius.circular(25.0),
                  boxShadow: [
                    new BoxShadow(
                      blurRadius: 5.0,
                      offset: const Offset(3.0, 0.0),
                      color: Colors.grey,
                    )
                  ]
                ),
                child: new Icon(Icons.monetization_on, size: 36.0, color: const Color.fromRGBO(218, 165, 32, 1.0))),
              new Positioned(
                left: 20.0,
                child: new Container(
                  decoration: new BoxDecoration(
                  borderRadius: BorderRadius.circular(25.0),
                  boxShadow: [
                    new BoxShadow(
                      blurRadius: 5.0,
                      offset: const Offset(3.0, 0.0),
                      color: Colors.grey,
                    )
                  ]
                ),
                  child: new Icon(Icons.monetization_on, size: 36.0, color: const Color.fromRGBO(218, 165, 32, 1.0))),
              ),
              new Positioned(
                left:40.0,
                child: new Container(
                  decoration: new BoxDecoration(
                  borderRadius: BorderRadius.circular(25.0),
                  boxShadow: [
                    new BoxShadow(
                      blurRadius: 5.0,
                      offset: const Offset(3.0, 0.0),
                      color: Colors.grey,
                    )
                  ]
                )
                  ,child: new Icon(Icons.monetization_on, size: 36.0, color: const Color.fromRGBO(218, 165, 32, 1.0))),
              )

            ],
          ),
        ),
      )
    ;
  }
}

截至2019 年 11 月,我想添加第二個解決方案:

使用包: https : //pub.dev/packages/assorted_layout_widgets

var widget1 = ...;
var widget2 = ...;

RowSuper(  
  children: [widget1, widget2],    
  innerDistance: -20.0,
  );

這將與行單元格重疊 20 個像素。

從該解決方案使用一個的不同StackPositioned在一個小部件Stack不占空間。 所以你不能讓Stack成為它的內容的大小,除非你事先知道它們的大小。 但是, RowSuper將具有其所有子小部件的大小。

請注意,還有一個ColumnSuper 還要注意我是這個包的作者。

我想要一些沒有依賴和硬編碼布局的東西。 您可以通過重疊使用媒體查詢來增強重疊百分比。

 Widget overlapped() {
    final overlap = 10.0;
    final items = [
      CircleAvatar(child: Text('1'), backgroundColor: Colors.red),
      CircleAvatar(child: Text('2'), backgroundColor: Colors.green),
      CircleAvatar(child: Text('3'), backgroundColor: Colors.blue),
    ];

    List<Widget> stackLayers = List<Widget>.generate(items.length, (index) {
      return Padding(
        padding: EdgeInsets.fromLTRB(index.toDouble() * overlap, 0, 0, 0),
        child: items[index],
      );
    });

    return Stack(children: stackLayers);
  }

OverflowBox包裝您的元素並賦予maxWidth值將實現此效果。

以下可以在一行或列表視圖中使用

 return SizedBox(
            width: 35, //--> list children will be 35 in width
            child: OverflowBox(
              maxWidth: 50, // --> allowing the child to overflow will cause overlap between elements
              child: Container(
                width: 50,
                child: Text((index + 1).toString()),
              ),
            ),
          );
    

這是我的個人資料圖片代碼,與顫動中的相機圖像重疊。

輸出:單擊此處查看輸出圖像

Container(
    constraints: new BoxConstraints(
      maxHeight: 200.0,
      maxWidth: 200.0
    ),
    padding: new EdgeInsets.only(left: 16.0, bottom: 8.0, right: 16.0),
    decoration: new BoxDecoration(
      shape: BoxShape.circle,
      image: new DecorationImage(
        image: new AssetImage('assets/images/profile.png'),
        fit: BoxFit.cover,
      ),
    ),
    child: Stack(
      children: [
        new Positioned(
          right: 0.0,
          bottom: 3.0,
          child: Container(
            constraints: new BoxConstraints(
                maxHeight: 50.0,
                maxWidth: 50.0
            ),
            decoration: new BoxDecoration(
              boxShadow: [
                BoxShadow(
                  color:Color(0xFFdedede),
                  offset: Offset(2,2)
                ),
              ],
              color: Colors.white,
              shape: BoxShape.circle,
            ),
            child: GestureDetector(
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: Icon(
                  Icons.photo_camera,
                  size: 34,
                  color: Color(0xFF00cde7),
                ),
              ),
            ),
          ),
        ),
      ],
    ),
  )

你可以試試我的包 ( signed_spacing_flex )。 它與普通Row (或ColumnFlex )完全相同。 但它也允許您設置負間距,這會導致其子項重疊。 您還可以設置重疊時哪些子項應位於頂部。

在你的情況下,它會是這樣的:

SignedSpacingRow(
  spacing: -12.0,
  stackingOrder: StackingOrder.lastOnTop,
  children: <Widget>[
    Icon(
      Icons.monetization_on, size: 36.0, 
      color: const Color.fromRGBO(218, 165, 32, 1.0),
    ),
    Icon(
      Icons.monetization_on, size: 36.0,
      color: const Color.fromRGBO(218, 165, 32, 1.0),
    ),
  ],
),

如果需要,它也適用於擴展的孩子。

基於@Lee Higgins的反向變體

const size = 32.0;
const overlap = size - 6.0;
final containers = [
  Container(
    decoration: BoxDecoration(
      color: Colors.grey[300],
      shape: BoxShape.circle,
    ),
    width: size,
    height: size,
  ),
  Container(
    decoration: BoxDecoration(
      color: Colors.grey[400],
      shape: BoxShape.circle,
    ),
    width: size,
    height: size,
  ),
];
List<Widget> stackLayers = List<Widget>.generate(containers.length, (index) {
  return Padding(
    padding: EdgeInsets.fromLTRB(0, 0, index * overlap, 0),
    child: containers[index],
  );
});
return Stack(alignment: AlignmentDirectional.topEnd, children: stackLayers);

堆棧非常混亂。 最好的解決方案是使用enter link description here

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM