Вот чего я пытаюсь достичь:
На небольшом устройстве, где все поля ввода не могут быть
отображены на одной странице, форма должна быть такой:
Но на большом экране, где все поля ввода
можно отобразить на одной странице, я хочу, чтобы было так:
(Обратите внимание на расстояние между кнопкой и последним введенным
поле должно быть динамичным, чтобы даже на планшетах кнопка
была внизу экрана)
Пожалуйста, прежде чем дать ответ, также проверьте, как он реагирует на открытие клавиатуры, я не хочу, чтобы кнопка перемещалась вверх... вот так:
Кроме того, конечно, я не хочу, чтобы клавиатура вызывала переполнение или делала поля ввода недоступными, я пробовал много вещей, но не нашел способа добиться этого, хотя это кажется простым проблема.
Вы можете обернуть свой код виджетом SingleChildScrollView
, который позволит вам прокручивать вниз без переполнения, а пользовательский интерфейс будет отзывчивым.
Для более подробной информации проверьте: это
Попробуйте следующий код:
Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
TextFormField(
decoration: InputDecoration(
hintText: 'Field 1',
border: OutlineInputBorder(
)
)
),
TextFormField(
decoration: InputDecoration(
hintText: 'Field 2',
border: OutlineInputBorder(
)
)
),TextFormField(
decoration: InputDecoration(
hintText: 'Field 3',
border: OutlineInputBorder(
)
)
),TextFormField(
decoration: InputDecoration(
hintText: 'Field 4',
border: OutlineInputBorder(
)
)
),TextFormField(
decoration: InputDecoration(
hintText: 'Field 5',
border: OutlineInputBorder(
)
)
),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.all(15),
child: FilledButton(
onPressed: (){},
child: Text('Submit'),
),
),
)
],
),
),
),
],
)
После этого вы можете заставить клавиатуру нажимать содержимое следующим образом:
В вашем Scaffold установите для свойства resizeToAvoidBottomInset
значение true
.
@MariosPlenchidis, хорошо, я только что заметил, вы можете переместить эту кнопку в столбец представления прокрутки, еще раз посмотрите на код.
Я использую LayoutBuilder
, SingleChildScrollView
и ConstrainedBox
, чтобы задать минимальную высоту Column
.
Чтобы разместить кнопку внизу, когда достаточно места, используйте Spacer
, а использование Spacer
внутри SingleChildScrollView
также потребует деформации Column
с помощью IntrinsicHeight
.
Этот подход продемонстрирован в документации SingleChildScrollView.
Чтобы избежать нажатия кнопки с клавиатуры, нам нужно получить viewInsets, используя MediaQuery.viewInsetsOf(context)
, и настроить его так, чтобы задать минимальную высоту Column
.
class A extends StatefulWidget {
const A({super.key});
@override
State<A> createState() => _AState();
}
class _AState extends State<A> {
int _number = 5;
@override
Widget build(BuildContext context) {
final viewInsets = MediaQuery.viewInsetsOf(context);
return Scaffold(
appBar: AppBar(
title: const Text('Demo'),
),
body: SafeArea(
child: LayoutBuilder(
builder: (context, constraints) {
final minHeight = constraints.maxHeight + viewInsets.bottom;
return SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ConstrainedBox(
constraints: BoxConstraints(minHeight: minHeight),
child: IntrinsicHeight(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text('ViewInsets: $viewInsets'),
Text('Constraints: $constraints'),
Text('minHeight: $minHeight'),
],
),
),
for (var i = 0; i < _number; i++)
const Card(
child: TextField(),
),
// This is for demo only, we could simply use a spacer here
const Expanded(
child: DecoratedBox(
decoration: BoxDecoration(
border: Border.fromBorderSide(BorderSide(color: Colors.red)),
),
),
),
DecoratedBox(
decoration: const BoxDecoration(
border: Border.fromBorderSide(BorderSide(color: Colors.blue)),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
IconButton.filled(
icon: const Icon(Icons.add),
onPressed: () {
setState(() {
_number++;
});
},
),
IconButton.filled(
icon: const Icon(Icons.remove),
onPressed: () {
setState(() {
_number--;
});
},
),
],
),
),
],
),
),
),
);
},
),
),
);
}
}
Это действительно хорошо! Как ты вообще об этом подумал.
Это не то поведение, которого я ожидаю. В вашем коде кнопка отправки всегда находится на экране. Посмотрите на первое изображение, которое я предоставил; Я хочу, чтобы кнопка была видна при прокрутке внизу.