#flutter #responsive-design
#flutter #адаптивный дизайн
Вопрос:
Я пытаюсь создать макет, подобный этому:
Класс макета, который я пытаюсь создать, выглядит следующим образом:
class Layout extends StatefulWidget {
@required
final String title;
@required
final Widget leftView;
@required
final Widget rightView;
const Layout({Key key, this.title, this.leftView, this.rightView})
: super(key: key);
@override
_LayoutState createState() => _LayoutState();
}
class _LayoutState extends State<Layout> {
String title;
Widget leftView;
Widget rightView;
@override
Widget build(BuildContext context) {
var screenSize = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
title: Text(title),
),
drawer: (screenSize.width < Constants.MOBILE_WIDTH_SIZE
? DrawerPage()
: null),
//TODO: Need to be able to change based on some global variable as comments section can't have something else down there
floatingActionButtonLocation:
screenSize.width < Constants.DESKTOP_WIDTH_SIZE
? FloatingActionButtonLocation.miniEndFloat
: FloatingActionButtonLocation.miniCenterFloat,
body: getRelevantLayout(screenSize.width, screenSize.height),
floatingActionButton: FloatingActionButton(
onPressed: () {
// Add your onPressed code here!
},
child: const Icon(Icons.add),
//backgroundColor: Colors.orangeAccent,
),
);
}
Widget getRelevantLayout(double _width, double _height) {
if (_width < Constants.MOBILE_WIDTH_SIZE) {
// mobile Layout
return leftView;
} else if (_width < Constants.DESKTOP_WIDTH_SIZE) {
// tablet layout
return Row(
children: [
DrawerPage(),
Expanded(
child: leftView,
),
],
);
} else {
// desktop layout
return Row(
children: [
DrawerPage(),
Flexible(flex: 9, child: leftView),
Flexible(flex: 10, child: rightView),
],
);
}
}
@override
void initState() {
title = widget.title;
leftView = widget.leftView;
rightView = widget.rightView;
super.initState();
}
}
Идея, которую я пытался реализовать, заключается в том, что в моих оригинальных маршрутах настраиваются мои представления, т. е
routes: {
'/': (context) => Layout(
title: '$_title - Home',
leftView: ListSectionView(),
rightView: WhatsNewView(),
),
Затем моя идея заключалась в том, чтобы, скажем, в leftview настроить rightView, хотя очевидно, что если leftview не настроен снова, это не сработает. Я хочу использовать обычную навигацию, только когда она отображается на планшете или телефоне.нажмите
Я изо всех сил старался найти подобное решение, но безрезультатно. Итак, любые предложения о том, как этого можно достичь, были бы высоко оценены.
Комментарии:
1. Пока я использую это в качестве вдохновения github.com/roughike/adaptive-master-detail-layouts . Не идеально то, что я хочу, но посмотрим, как далеко это может зайти
2. Этот пакет может быть интересен pub.dev/packages/responsive_scaffold
3. @pavel спасибо, но, похоже, это всего лишь несколько каркасов и что-то похожее на то, что я ранее связал. Идея заключалась в том, чтобы использовать тот же каркас, чтобы панель вверху растягивала экран
Ответ №1:
Мне нравится создавать целое дерево виджетов для каждой ориентации в отдельном виджете и выбирать, какой из них использовать, в зависимости от ширины экрана и ориентации. Я использую константы для размеров экрана и функций, когда хочу изменить размер только нескольких компонентов. Пример:
const double smallScreenWidth = 360.0;
const double mediumScreenWidth = 412.0;
const double bigScreenWidth = 480.0;
double iconSize(BuildContext context) {
double screenWidth = 1;
if (MediaQuery.of(context).orientation == Orientation.portrait)
screenWidth = MediaQuery.of(context).size.width;
else
screenWidth = MediaQuery.of(context).size.height;
if (screenWidth <= smallScreenWidth)
return 32.0;
else if (screenWidth <= mediumScreenWidth)
return 40.0;
else
return 48.0;
}
Комментарии:
1. @rar0x спасибо, я, конечно, делаю что-то подобное, но моя главная проблема в том, что я хотел, чтобы 3 экрана знали, где это было. Я думаю, мне, возможно, придется просто попробовать то, что я делаю, поскольку я не думаю, что кто-то может это увидеть. Моя главная проблема заключалась в том, что я не хотел получать дополнительные данные из API, пока он не откроет страницу.
2. У меня есть приложение с похожим поведением. Я использую навигацию только при небольшом размере экрана. Когда он большой, я показываю все на одном экране. Это работает отлично. Вы можете выполнять дополнительные вызовы API, только если это необходимо для создания дополнительной части (ваш правый экран).
3. вы просто делаете drawer и leftView (используя этот пример), хотя?
4. Вы можете выполнить три представления. Для третьего представления вы бы использовали FutureBuilder (или StreamBuilder) или любой другой виджет, который создается на основе будущего результата. Тогда вы можете вызывать API только тогда, когда требуется третье представление. Вы решаете, использовать третий вид или нет, исходя из ширины экрана.