问题描述
我有 3 个具有动态 gridview 的选项卡,但我的问题是,当我在物理设备上测试它时,其中一个 gridview 的末端看起来完整,但在另一个较小的设备 (720 x 1280) 中gridview的最后一行文字不可见,所以我的想法是在底部添加一个填充,但当然,在小设备上它看起来不错
并将此填充添加到 GridView.Builder...:
padding: EdgeInsets.only(right: 20.0,left: 20.0,bottom: 100),
但在其他更高分辨率的设备中,这使得底部的填充看起来不一样,这里的填充更大"
如何进行这种动态填充,使其相同并且网格视图在所有设备上都完全可见?
另外,我想补充一点,我的 TabBarViews 在一个 500 高度的容器内,我不知道这是否有问题,因为我觉得它是静态的,我不喜欢任何东西,我想要容器只从头开始(在选项卡下方)直到屏幕结束,我也不知道该怎么做。
另外,我看到测试总是指出安全区域和脚手架下的列有“hasSize”问题,我在尝试修复它时总是遇到许多高度异常,在 shop_scree_page.dart 中,我不不太了解设计,也许我把事情搞错了。
shop_scree_page.dart
import 'package:Flutter/material.dart';
import 'package:Flutter/services.dart';
import 'package:plantsapp/screens/all_tab.dart';
import 'package:plantsapp/screens/indoor_page.dart';
import 'package:plantsapp/screens/outdoor_tab.dart';
import 'package:plantsapp/screens/top_tab.dart';
import 'package:plantsapp/services/authentication_service.dart';
class ShopScreen extends StatefulWidget {
@override
_ShopScreenState createState() => _ShopScreenState();
}
class _ShopScreenState extends State<ShopScreen>
with SingleTickerProviderStateMixin {
TabController _tabController;
PageController _pageController;
GlobalKey<ScaffoldState> _drawerKey = GlobalKey();
@override
void initState() {
super.initState();
_tabController = TabController(initialIndex: 0,length: 4,vsync: this);
_pageController = PageController(initialPage: 0,viewportFraction: 0.8);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
List<Widget> containers = [
new TopTab(),new OutdoorTab(),new IndoorTab(),new AllTab(),];
AuthenticationService authServ = new AuthenticationService();
return Scaffold(
key: _drawerKey,drawer: new Drawer(),floatingActionButton: FloatingActionButton(
child: Icon(Icons.logout),backgroundColor: Colors.black,onpressed: () {
//context.read<AuthenticationService>()
authServ.signOut();
},),drawerEnableOpenDragGesture: false,body: SafeArea(
child: Column(
children: <Widget>[
//ICONOS MENU Y CART
Container(
margin: EdgeInsets.only(top: 20),child: Padding(
padding: EdgeInsets.symmetric(horizontal: 30.0),child: Row(
mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
IconButton(
icon: Icon(Icons.menu,size: 30.0,color: Colors.grey),onpressed: (() => _drawerKey.currentState.openDrawer()),Spacer(),IconButton(
icon: Icon(Icons.add),color: Colors.black,iconSize: 32,onpressed: () {
Navigator.pushNamed(context,'createplantpost');
}),IconButton(
icon: Icon(Icons.shopping_cart),onpressed: () {}),],SizedBox(height: 20.0),//TITULO "TOP PICKS"
Expanded(
child: Container(
width: double.infinity,child: SingleChildScrollView(
child: Column(
children: [
Container(
alignment: Alignment.centerLeft,child: Padding(
padding: EdgeInsets.only(left: 20.0),child: Text(
'Top Picks',style: TextStyle(
fontSize: 24.0,fontWeight: FontWeight.w600),_tabs(),_tabsView(containers),);
}
Widget _tabs() {
return TabBar(
controller: _tabController,indicatorColor: Colors.transparent,labelColor: Colors.black,unselectedLabelColor: Colors.grey.withOpacity(0.6),labelPadding: EdgeInsets.symmetric(horizontal: 35.0),isScrollable: true,tabs: <Widget>[
Tab(
child: Text('Top',style: TextStyle(
fontSize: 16.0,fontWeight: FontWeight.w600,))),Tab(
child: Text('Outdoor',Tab(
child: Text('Indoor',Tab(
child: Text('All',);
}
Widget _tabsView(containers) {
final size = MediaQuery.of(context).size;
return Container(
height: 500,child: TabBarView(
physics: NeverScrollableScrollPhysics(),controller: _tabController,children: containers
),);
}
}
outdoor_tab.dart
import 'package:Flutter/material.dart';
import 'package:plantsapp/models/plant_model.dart';
import 'package:plantsapp/providers/products_provider.dart';
import 'package:plantsapp/screens/plant_screen.dart';
import 'package:plantsapp/widgets/snapshots_alerts.dart';
class OutdoorTab extends StatefulWidget {
const OutdoorTab({Key key}) : super(key: key);
@override
_OutdoorTabState createState() => _OutdoorTabState();
}
class _OutdoorTabState extends State<OutdoorTab> {
@override
Widget build(BuildContext context) {
ProductsProvider productsProvider = new ProductsProvider();
return Scaffold(
body: streamBuilderCards(productsProvider),);
}
Widget streamBuilderCards(ProductsProvider productsProvider) {
final size = MediaQuery.of(context).size;
return StreamBuilder(
stream: productsProvider.getPostOutdoor(context),builder:
(BuildContext context,AsyncSnapshot<List<PlantModel>> snapshot) {
if (snapshot.hasError) {
return snapshotMsgError(snapshot);
}
if (!snapshot.hasData) {
return snapshotCircularProgressIndicator();
}
List<PlantModel> posts = snapshot.data;
return GridView.builder(
padding: EdgeInsets.only(
right: 20.0,itemCount: posts.length,gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,mainAxisspacing: 20,crossAxisspacing: 20,childAspectRatio: 0.60),itemBuilder: (context,index) => ItemCard(plants: posts[index]),);
},);
}
}
class ItemCard extends StatelessWidget {
final PlantModel plants;
final Function press;
const ItemCard({
Key key,this.press,this.plants,}) : super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
Navigator.push(
context,MaterialPageRoute(
builder: (_) => PlantScreen(plant: plants),child: Column(
crossAxisAlignment: CrossAxisAlignment.start,children: [
Container(
height: 198,width: 175,decoration: Boxdecoration(
//color: Colors.blueAccent,borderRadius: BorderRadius.circular(16)),child: Hero(
tag: plants.imageUrl,child: ClipRRect(
borderRadius: BorderRadius.circular(16),child: (plants.imageUrl == null)
? Image(
image: Assetimage('assets/images/no-image.png'),fit: BoxFit.cover)
: FadeInImage(
image: NetworkImage(plants.imageUrl),placeholder:
Assetimage('assets/images/image-loading.gif'),fit: BoxFit.cover,/*Image(
image: NetworkImage(plants.imageUrl),)*/
),) //Image.asset(plants.imageUrl),Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),child: Text(
plants.name,style: TextStyle(color: Colors.grey),overflow: TextOverflow.ellipsis,Text(
'\$${plants.price}',style: TextStyle(fontWeight: FontWeight.bold),)
],);
}
}
解决方法
您可以通过屏幕尺寸动态填充来实现这一点。对于经验:
var screenHeight = MediaQuery.of(context).size.height;
var screenWidth = MediaQuery.of(context).size.width;
padding: EdgeInsets.only(right: screenWidth * 0.2,left: screenWidth * 0.2,bottom: screenHeight * 0.15)