При изменении ширины контейнера по умолчанию изменяется размер справа. В приведенном ниже псевдокоде есть пример, где dx — это переменная, которая может изменяться. Когда он увеличивается или уменьшается, контейнер всегда будет увеличиваться или уменьшаться с правой стороны. Есть ли простой способ переключить направление, чтобы ширина увеличивалась или уменьшалась с левой стороны, а не с правой?
Container(
width: dx,
height:200
)
Вот суть дротика, показывающая, как правая сторона ширины контейнера изменяется при перетаскивании. Я спрашиваю, есть ли быстрый и простой способ расширить/сжать левую сторону без необходимости анимации положения контейнера: https://dartpad.dev/?id=ebbe57041bf950018fe5733674c68b20
@YeasinSheikh Я добавил суть дротика, чтобы лучше понять идею. Вы можете перетаскивать правую сторону, но логика левой стороны должна работать так же. Мне интересно, есть ли общий способ сделать это, который так же прост, как и расширение/сжатие правой стороны путем изменения ширины.
Я думаю, вы можете играть с alingment
собственностью
Не уверен, как это могло бы работать, поскольку мое понимание выравнивания заключается в том, что оно связано с тем, как дочерние элементы выравниваются внутри контейнера. Вы можете остановиться на этом?
Я проверил твой код дротика. Чтобы достичь того, чего вы хотите, я предлагаю вам поместить два пустых Containers
по обе стороны от ваших ручек и уменьшить их размер при перетаскивании ручек (ваш центр Container
также должен быть внутри виджета Expanded
, чтобы занимать все разрешенное пространство). вот пример кода:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
// Application name
title: 'Flutter Stateful Clicker Counter',
theme: ThemeData(
// Application theme data, you can set the colors for the application as
// you want
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Clicker Counter Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
const MyHomePage({Key? key, required this.title}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
double? rightContainerWidth, leftContainerWidth;
@override
Widget build(BuildContext context) {
rightContainerWidth ??= MediaQuery.of(context).size.width / 2 - 20;
leftContainerWidth ??= MediaQuery.of(context).size.width / 2 - 20;
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Wrap(
children: <Widget>[
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
// left handle
Container(
width: leftContainerWidth,
),
GestureDetector(
onHorizontalDragUpdate: (DragUpdateDetails details) {
setState(() {
leftContainerWidth = details.globalPosition.dx;
});
},
child: Container(
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
bottomLeft: Radius.circular(20),
)),
width: 10,
height: 200)),
Expanded(
child: Container(
// padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
child: ClipRect(
child: Container(
// width: _counter+0.2,
height: 200,
color: Colors.green,
))),
),
GestureDetector(
onHorizontalDragStart: (DragStartDetails details) {
print("st: ${details.localPosition.dx}");
// dx for start is the x offset of the mouse relative to the container
// changeX = (_counter as double) - details.localPosition.dx.floor();
},
onHorizontalDragUpdate: (DragUpdateDetails details) {
setState(() {
// print(details.localPosition.dx);
rightContainerWidth = MediaQuery.of(context).size.width -
details.globalPosition.dx;
});
},
child: Container(
width: 10,
height: 200,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.only(
topRight: Radius.circular(20),
bottomRight: Radius.circular(20),
)))),
Container(
width: rightContainerWidth,
),
])
],
),
),
);
}
}
Внимание: я не добавлял условные операторы для предотвращения переполнения, убедитесь, что вы их тоже добавили!
Я понимаю, что вы имеете в виду. mainAxisAlignment.end
заставит контейнер смещаться на другую сторону и расти с противоположной стороны, но видимый сдвиг в конец нежелателен. Придется переключаться между mainAxisAlignment.end
и mainAxisAlignment.start
без видимого изменения выравнивания.
тогда я не понимаю, что вы имеете в виду под ростом с левой стороны. Если ваши виджеты находятся в левой части экрана, и вы хотите, чтобы они росли слева, это приведет к переполнению.
В мишени для дротиков вы видели, как контейнер расширяется справа при перетаскивании правой ручки. Что необходимо, так это то, что контейнер должен расширяться слева при перетаскивании левой ручки. Не имеет значения, выровнен ли контейнер по началу или концу главной оси. Один из способов заставить это работать слева — изменить положение контейнера, одновременно изменяя ширину. Я надеялся, что будет какой-то еще более простой способ сделать это во флаттере.
О, кажется, теперь я понимаю, что вы имеете в виду. Я отредактировал свой ответ. Надеюсь, поможет
Это решение включает в себя дополнительные контейнеры. Я надеялся, что во флаттере есть какая-то еще более простая вещь, которая позволит это сделать, но похоже, что есть две опции: перемещение контейнера при настройке ширины или использование расширенного контейнера и настройка двух дополнительных контейнеров. Я выберу это как ответ.
@Kdigital, я думаю, вы больше привыкли к тому, как работает нативная разработка для Android. Во флаттере такого нет. Виджеты размещаются в зависимости от их размера и выравнивания их родителей.
Используйте виджет Wrap
Виджет, который отображает своих дочерних элементов в нескольких горизонтальных или вертикальных прогонах.
Обертка размещает каждый дочерний элемент и пытается поместить дочерний элемент рядом с предыдущим дочерним элементом на главной оси, заданной направлением, оставляя пространство между ними. Если для размещения дочернего элемента недостаточно места, Wrap создает новый участок рядом с существующими дочерними элементами на поперечной оси.
После того, как все дочерние элементы распределены по трассам, дочерние элементы внутри трасс располагаются в соответствии с выравниванием по главной оси и в соответствии с crossAxisAlignment по поперечной оси.
Затем сами прогоны располагаются на поперечной оси в соответствии с параметрами runSpacing и runAlignment.
Пример:
Wrap(
spacing: 8.0, // gap between adjacent chips
runSpacing: 4.0, // gap between lines
children: <Widget>[
Chip(
avatar: CircleAvatar(backgroundColor: Colors.blue.shade900, child: const Text('AH')),
label: const Text('Hamilton'),
),
Chip(
avatar: CircleAvatar(backgroundColor: Colors.blue.shade900, child: const Text('ML')),
label: const Text('Lafayette'),
),
Chip(
avatar: CircleAvatar(backgroundColor: Colors.blue.shade900, child: const Text('HM')),
label: const Text('Mulligan'),
),
Chip(
avatar: CircleAvatar(backgroundColor: Colors.blue.shade900, child: const Text('JL')),
label: const Text('Laurens'),
),
],
)
можете ли вы включить полный образец виджета из тела скаффолда. В трепетном положении ребенка.