Container GridView의 높이를 지정한 후에도 내 코드는 사각형 위젯을 생성합니다.
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<String> widgetList = ['A', 'B', 'C'];
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Container(
child: new GridView.count(
crossAxisCount: 2,
controller: new ScrollController(keepScrollOffset: false),
shrinkWrap: true,
scrollDirection: Axis.vertical,
children: widgetList.map((String value) {
return new Container(
height: 250.0,
color: Colors.green,
margin: new EdgeInsets.all(1.0),
child: new Center(
child: new Text(
value,
style: new TextStyle(fontSize: 50.0,color: Colors.white),
),
),
);
}).toList(),
),
),
);
}
}
위 코드의 출력은 왼쪽과 같습니다. 오른쪽에 표시된대로 사용자 지정 높이 위젯이있는 GridView를 얻으려면 어떻게해야합니까?
답변
핵심은 childAspectRatio
. 이 값은에서 레이아웃을 결정하는 데 사용됩니다 GridView
. 원하는 화면을 얻으려면 ( itemWidth
/ itemHeight
) 로 설정해야합니다 . 해결책은 다음과 같습니다.
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<String> widgetList = ['A', 'B', 'C'];
@override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
/*24 is for notification bar on Android*/
final double itemHeight = (size.height - kToolbarHeight - 24) / 2;
final double itemWidth = size.width / 2;
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Container(
child: new GridView.count(
crossAxisCount: 2,
childAspectRatio: (itemWidth / itemHeight),
controller: new ScrollController(keepScrollOffset: false),
shrinkWrap: true,
scrollDirection: Axis.vertical,
children: widgetList.map((String value) {
return new Container(
color: Colors.green,
margin: new EdgeInsets.all(1.0),
child: new Center(
child: new Text(
value,
style: new TextStyle(
fontSize: 50.0,
color: Colors.white,
),
),
),
);
}).toList(),
),
),
);
}
}
답변
며칠 전 인터넷에서 이미지를로드 할 때 높이를 동적으로 변경하는 방법을 찾기 위해 여기에 왔으며 childAspectRatio
GridView의 모든 위젯에 적용되기 때문에 사용할 수 없습니다 (각각에 대해 동일한 높이).
이 답변은 각각의 모든 위젯 콘텐츠에 따라 다른 높이를 원하는 사람에게 도움이 될 수 있습니다.
Romain Rastel의 Flutter Staggered GridView 라는 패키지를 찾았습니다 . 이 패키지를 사용하여 우리는 여기에서 예제를 확인하는 많은 일을 할 수 있습니다.
우리가 원하는 것을 얻기 위해 우리가 사용할 수 StaggeredGridView.count()
있는 속성 staggeredTiles:
과 그 값에 대해 모든 위젯을 매핑하고 적용 할 수 있습니다 StaggeredTile.fit(2)
.
예제 코드 :
StaggeredGridView.count(
crossAxisCount: 4, // I only need two card horizontally
padding: const EdgeInsets.all(2.0),
children: yourList.map<Widget>((item) {
//Do you need to go somewhere when you tap on this card, wrap using InkWell and add your route
return new Card(
child: Column(
children: <Widget>[
Image.network(item.yourImage),
Text(yourList.yourText),//may be the structure of your data is different
],
),
);
}).toList(),
//Here is the place that we are getting flexible/ dynamic card for various images
staggeredTiles: yourList.map<StaggeredTile>((_) => StaggeredTile.fit(2))
.toList(),
mainAxisSpacing: 3.0,
crossAxisSpacing: 4.0, // add some space
),
);
여기 에서 전체 예제 (복사, 붙여 넣기 및 실행)를 찾을 수 있습니다 .
답변
crossAxisCount
, crossAxisSpacing
화면 너비가 결정 width
하고 childAspectRatio
결정 height
합니다.
나는 그들 사이의 관계를 알아 내기 위해 약간의 계산을했다.
var width = (screenWidth - ((_crossAxisCount - 1) * _crossAxisSpacing)) / _crossAxisCount;
var height = width / _aspectRatio;
전체 예 :
double _crossAxisSpacing = 8, _mainAxisSpacing = 12, _aspectRatio = 2;
int _crossAxisCount = 2;
@override
Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
var width = (screenWidth - ((_crossAxisCount - 1) * _crossAxisSpacing)) / _crossAxisCount;
var height = width / _aspectRatio;
return Scaffold(
body: GridView.builder(
itemCount: 10,
itemBuilder: (context, index) => Container(color: Colors.blue[((index) % 9) * 100]),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: _crossAxisCount,
crossAxisSpacing: _crossAxisSpacing,
mainAxisSpacing: _mainAxisSpacing,
childAspectRatio: _aspectRatio,
),
),
);
}
답변
그것은 나를 위해 일하고 있습니다.
예제 코드 :
var _crossAxisSpacing = 8;
var _screenWidth = MediaQuery.of(context).size.width;
var _crossAxisCount = 2;
var _width = ( _screenWidth - ((_crossAxisCount - 1) * _crossAxisSpacing)) / _crossAxisCount;
var cellHeight = 60;
var _aspectRatio = _width /cellHeight;
GridView :
GridView.builder(
padding: EdgeInsets.only(
left: 5.0, right: 5.0, top: 10, bottom: 10),
shrinkWrap: false,
itemCount: searchList.length,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: _crossAxisCount,childAspectRatio: _aspectRatio),
itemBuilder: (context, index) {
final item = searchList[index];
return Card(
child: ListTile(
title: Text(item.name,maxLines: 1,overflow: TextOverflow.ellipsis),
trailing: Container(
width: 15,
height: 15,
decoration: BoxDecoration(
color: item.isActive == true
? Theme.of(context).primaryColor
: Colors.red,
borderRadius: BorderRadius.all(
Radius.circular(50))),
),
onTap: () {
},
),
elevation: 0.5,
);
},
)