Получение 'Горизонтальная область просмотра получила неограниченную высоту.' с TabBarView во флаттере
Я пытаюсь сделать страницу профиля, где информация о пользователях находится вверху. И затем есть представление вкладки ниже, что для разных представлений.
Это код, который я использую в тот момент, когда я беру TabBarView
это не из-за ошибки, и если я заверну TabBarView
в Expanded
Ошибка RenderFlex children have non-zero flex but incoming height constraints are unbounded.
подходит
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(''),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.all(10.0),
child: Row(
children: <Widget>[
CircleAvatar(
minRadius: 45.0,
backgroundImage: NetworkImage(
'https://www.ienglishstatus.com/wp-content/uploads/2018/04/Anonymous-Whatsapp-profile-picture.jpg'),
),
Padding(
padding: EdgeInsets.only(left: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Testing Name',
style: TextStyle(
fontSize: 22.0,
color: Colors.grey.shade800,
),
),
Text(
'@testing_username',
style: TextStyle(
fontSize: 13.0,
color: Colors.grey.shade800,
),
),
],
),
),
],
),
),
DefaultTabController(
length: 3,
child: Column(
children: <Widget>[
TabBar(
tabs: <Widget>[
Tab(
icon: Padding(
padding: EdgeInsets.all(6.0),
child: Image.asset(
"assets/images/icons/butterlike.png",
color: Colors.grey.shade800,
),
),
),
Tab(
icon: Padding(
padding: EdgeInsets.all(6.0),
child: Image.asset(
"assets/images/icons/butterlike.png",
color: Colors.grey.shade800,
),
),
),
Tab(
icon: Padding(
padding: EdgeInsets.all(6.0),
child: Image.asset(
"assets/images/icons/butterlike.png",
color: Colors.grey.shade800,
),
),
),
],
),
TabBarView(
children: <Widget>[
Container(
color: Colors.grey,
),
Container(
color: Colors.green,
),
Container(
color: Colors.purple,
),
],
),
],
),
)
],
),
);
}
Я попробовал вариант этого, но не смог заставить его работать.
5 ответов
Описание ошибки понятно, TabBarView не имеет ограниченной высоты. родительский виджет также не имеет ограниченной высоты. Таким образом, расширенный виджет не решит эту проблему.
РЕДАКТИРОВАТЬ: ниже решения для вышеуказанного вопроса (с колонками). В общих случаях, используйте ListView с shrinkWrap: true
.(Или любые другие виджеты с shrinkWrap)
Есть несколько вариантов:
Первое решение:
Оберните родительский виджет (Столбец) виджетом с ограниченной высотой, таким как SizedBox или AspectRatio. Затем используйте расширенный виджет следующим образом:
child: SizedBox(
height: 300.0,
child: Column(
children: <Widget>[
.
.
.
Expanded(
child: TabBarView(
children: <Widget>[
Container(
height: 200.0,
color: Colors.grey,
),
Container(
height: 200.0,
color: Colors.green,
),
Container(
height: 200.0,
color: Colors.purple,
),
],
),
),
],
),
),
Второе решение:
Используйте ограниченный виджет, такой как SizedBox или AspectRatio, на самом TabBarView:
SizedBox(
height: 300.0,
child: TabBarView(
children: <Widget>[
Container(
height: 200.0,
color: Colors.grey,
),
Container(
height: 200.0,
color: Colors.green,
),
Container(
height: 200.0,
color: Colors.purple,
),
],
),
),
Примечание Вы также можете рассчитать высоту динамически, если высота не является статичной.
Попробуй использовать IndexedStack
вместо того TabBarView
Я попытался Expanded
, shrinkWrap = true
,... но никто не работает нормально, просто попробуйте пример.
Пример:
class Product extends StatefulWidget {
@override
_ProductState createState() => _ProductState();
}
class _ProductState extends State<Product> with SingleTickerProviderStateMixin {
TabController tabController;
int selectedIndex = 0;
@override
void initState() {
super.initState();
tabController = TabController(length: 5, vsync: this, initialIndex: 0);
}
@override
void dispose() {
tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
initialIndex: 0,
child: Scaffold(
body: ListView(
shrinkWrap: true,
children: [
TabBar(
tabs: <Widget>[
Tab(
text: 'one',
),
Tab(
text: 'two',
),
Tab(
text: 'three',
),
],
controller: tabController,
onTap: (index) {
setState(() {
selectedIndex = index;
tabController.animateTo(index);
});
},
),
IndexedStack(
children: <Widget>[
Visibility(
child: Text('test1'),
maintainState: true,
visible: selectedIndex == 0,
),
Visibility(
child: Text('test2'),
maintainState: true,
visible: selectedIndex == 1,
),
Visibility(
child: Text('test3'),
maintainState: true,
visible: selectedIndex == 2,
),
],
index: selectedIndex,
),
],
),
),
);
}
}
особая благодарность Arbalest
Я решил это, добавив TabBar
внутри Container
а также TabBarView
внутри Expanded
:
DefaultTabController(
length: 3,
child: Column(
children: <Widget>[
Container(child: TabBar(..)),
Expanded(child: TabBarView(..)),
],
),
);
На основе ответа @Yamin я использовал SizeBox, как показано ниже, чтобы получить полную страницу
SizedBox.expand(
child: TabBarView(),
)
или любой другой размер:
SizedBox(
height: height:MediaQuery.of(context).size.height // or every other size ,
child: TabBarView(),
)
В сообщении об ошибке в консоли упоминается следующее: «Видовые экраны расширяются по поперечной оси, чтобы заполнить свой контейнер, и ограничивают своих дочерних элементов, чтобы они соответствовали их размеру по поперечной оси. В этом случае горизонтальному видовому экрану было предоставлено неограниченное количество вертикального пространства, в котором можно расширять". Очевидно, что горизонтальное окно просмотра здесь относится к виджету TabBarView, для которого не задано ограничение по высоте. Поэтому оберните виджеты TabBar и TabBarView в расширенные виджеты и задайте им соответствующие значения гибкости, чтобы они могли разделить высоту своего родителя. Конкретно,
DefaultTabController(
length: 3,
child: Column(
children: <Widget>[
Expanded(
flex: 1,
child: TabBar(
tabs: <Widget>[
Tab(
icon: Padding(
padding: EdgeInsets.all(6.0),
child: Image.asset(
"assets/images/icons/butterlike.png",
color: Colors.grey.shade800,
),
),
),
Tab(
icon: Padding(
padding: EdgeInsets.all(6.0),
child: Image.asset(
"assets/images/icons/butterlike.png",
color: Colors.grey.shade800,
),
),
),
Tab(
icon: Padding(
padding: EdgeInsets.all(6.0),
child: Image.asset(
"assets/images/icons/butterlike.png",
color: Colors.grey.shade800,
),
),
),
],
),
),
Expanded(
flex: 9,
child: TabBarView(
children: <Widget>[
Container(
color: Colors.grey,
),
Container(
color: Colors.green,
),
Container(
color: Colors.purple,
),
],
),
)
],
),
)