У меня есть 3 вкладки с динамическим представлением сетки, но моя проблема в том, что, когда я тестировал его на физическом устройстве, на одном из них конец представления сетки выглядел завершенным, но на другом меньшем устройстве (720 x 1280) последняя строка the gridview Текст не был виден, поэтому я подумал добавить отступ внизу, но, конечно, на маленьком устройстве это выглядит нормально
И добавляем этот отступ в GridView.Builder ...:
padding: EdgeInsets.only(right: 20.0, left: 20.0, bottom: 100),
но в других устройствах с более высоким разрешением из-за этого отступ внизу не выглядит одинаково, а здесь отступ больше
Как я могу сделать это динамическое заполнение, чтобы оно было одинаковым и сетка была полностью видна на всех устройствах?
Кроме того, я хочу добавить, что мои TabBarViews находятся внутри контейнера высотой 500, и я не знаю, может ли это быть проблемой, потому что я чувствую, что он статичен, и мне ничего не нравится, я бы хотел, чтобы контейнер был только доводить до конца экрана с самого начала (под вкладками), и я тоже не знаю, как это сделать.
Кроме того, я видел, что при тестировании всегда указывалось, что столбец под safearea и scaffold имел проблемы 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),
color: Colors.black,
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',
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.w600,
))),
Tab(
child: Text('Indoor',
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.w600,
))),
Tab(
child: Text('All',
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.w600,
))),
],
);
}
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, left: 20.0, bottom: 100),
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),
fit: BoxFit.cover,
)*/
),
) //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),
)
],
),
);
}
}