Merge pull request #452 from estevez-dev/feature/tablet_ui
Feature/tablet ui
This commit is contained in:
commit
a71213c589
@ -113,4 +113,5 @@ class Sizes {
|
|||||||
static const inputWidth = 160.0;
|
static const inputWidth = 160.0;
|
||||||
static const rowPadding = 10.0;
|
static const rowPadding = 10.0;
|
||||||
static const doubleRowPadding = rowPadding*2;
|
static const doubleRowPadding = rowPadding*2;
|
||||||
|
static const minViewColumnWidth = 350;
|
||||||
}
|
}
|
@ -25,6 +25,7 @@ import 'package:in_app_purchase/in_app_purchase.dart';
|
|||||||
import 'plugins/circular_slider/single_circular_slider.dart';
|
import 'plugins/circular_slider/single_circular_slider.dart';
|
||||||
import 'package:share/receive_share_state.dart';
|
import 'package:share/receive_share_state.dart';
|
||||||
import 'package:share/share.dart';
|
import 'package:share/share.dart';
|
||||||
|
import 'plugins/DynamicMultiColumnLayout.dart';
|
||||||
|
|
||||||
import 'utils/logger.dart';
|
import 'utils/logger.dart';
|
||||||
|
|
||||||
|
146
lib/plugins/DynamicMultiColumnLayout.dart
Normal file
146
lib/plugins/DynamicMultiColumnLayout.dart
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/rendering.dart';
|
||||||
|
import 'dart:math' as math;
|
||||||
|
|
||||||
|
class DynamicMultiColumnLayout extends MultiChildRenderObjectWidget {
|
||||||
|
|
||||||
|
final int minColumnWidth;
|
||||||
|
|
||||||
|
DynamicMultiColumnLayout({
|
||||||
|
Key key,
|
||||||
|
this.minColumnWidth: 350,
|
||||||
|
List<Widget> children = const <Widget>[],
|
||||||
|
}) : super(key: key, children: children);
|
||||||
|
|
||||||
|
@override
|
||||||
|
RenderCustomLayoutBox createRenderObject(BuildContext context) {
|
||||||
|
return RenderCustomLayoutBox(minColumnWidth: this.minColumnWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class RenderCustomLayoutBox extends RenderBox
|
||||||
|
with ContainerRenderObjectMixin<RenderBox, CustomLayoutParentData>,
|
||||||
|
RenderBoxContainerDefaultsMixin<RenderBox, CustomLayoutParentData> {
|
||||||
|
|
||||||
|
final int minColumnWidth;
|
||||||
|
|
||||||
|
RenderCustomLayoutBox({
|
||||||
|
this.minColumnWidth,
|
||||||
|
List<RenderBox> children,
|
||||||
|
}) {
|
||||||
|
addAll(children);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void setupParentData(RenderBox child) {
|
||||||
|
if (child.parentData is! CustomLayoutParentData) {
|
||||||
|
child.parentData = CustomLayoutParentData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double _getIntrinsicHeight(double childSize(RenderBox child)) {
|
||||||
|
double inflexibleSpace = 0.0;
|
||||||
|
RenderBox child = firstChild;
|
||||||
|
while (child != null) {
|
||||||
|
inflexibleSpace += childSize(child);
|
||||||
|
final FlexParentData childParentData = child.parentData;
|
||||||
|
child = childParentData.nextSibling;
|
||||||
|
}
|
||||||
|
return inflexibleSpace;
|
||||||
|
}
|
||||||
|
|
||||||
|
double _getIntrinsicWidth(double childSize(RenderBox child)) {
|
||||||
|
double maxSpace = 0.0;
|
||||||
|
RenderBox child = firstChild;
|
||||||
|
while (child != null) {
|
||||||
|
maxSpace = math.max(maxSpace, childSize(child));
|
||||||
|
final FlexParentData childParentData = child.parentData;
|
||||||
|
child = childParentData.nextSibling;
|
||||||
|
}
|
||||||
|
return maxSpace;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
double computeMinIntrinsicWidth(double height) {
|
||||||
|
return _getIntrinsicWidth((RenderBox child) => child.getMinIntrinsicWidth(height));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
double computeMaxIntrinsicWidth(double height) {
|
||||||
|
return _getIntrinsicWidth((RenderBox child) => child.getMaxIntrinsicWidth(height));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
double computeMinIntrinsicHeight(double width) {
|
||||||
|
return _getIntrinsicHeight((RenderBox child) => child.getMinIntrinsicHeight(width));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
double computeMaxIntrinsicHeight(double width) {
|
||||||
|
return _getIntrinsicHeight((RenderBox child) => child.getMaxIntrinsicHeight(width));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void performLayout() {
|
||||||
|
int columnsCount;
|
||||||
|
List<double> columnXPositions = [];
|
||||||
|
List<double> columnYPositions = [];
|
||||||
|
if (childCount == 0) {
|
||||||
|
size = constraints.biggest;
|
||||||
|
assert(size.isFinite);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
columnsCount = (constraints.maxWidth ~/ this.minColumnWidth);
|
||||||
|
double columnWidth = constraints.maxWidth / columnsCount;
|
||||||
|
double startY = 0;
|
||||||
|
for (int i =0; i < columnsCount; i++) {
|
||||||
|
columnXPositions.add(i*columnWidth);
|
||||||
|
columnYPositions.add(startY);
|
||||||
|
}
|
||||||
|
RenderBox child = firstChild;
|
||||||
|
while (child != null) {
|
||||||
|
final CustomLayoutParentData childParentData = child.parentData;
|
||||||
|
|
||||||
|
int columnToAdd = 0;
|
||||||
|
double minYPosition = columnYPositions[0];
|
||||||
|
for (int i=0; i<columnsCount; i++) {
|
||||||
|
if (columnYPositions[i] < minYPosition) {
|
||||||
|
minYPosition = columnYPositions[i];
|
||||||
|
columnToAdd = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
child.layout(BoxConstraints.tightFor(width: columnWidth), parentUsesSize: true);
|
||||||
|
childParentData.offset = Offset(columnXPositions[columnToAdd], columnYPositions[columnToAdd]);
|
||||||
|
final Size newSize = child.size;
|
||||||
|
columnYPositions[columnToAdd] = minYPosition + newSize.height;
|
||||||
|
|
||||||
|
child = childParentData.nextSibling;
|
||||||
|
}
|
||||||
|
|
||||||
|
double width = constraints.maxWidth;
|
||||||
|
double height = 0;
|
||||||
|
for (int i=0; i<columnsCount; i++) {
|
||||||
|
if (columnYPositions[i] > height) {
|
||||||
|
height = columnYPositions[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size = Size(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void paint(PaintingContext context, Offset offset) {
|
||||||
|
defaultPaint(context, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool hitTestChildren(HitTestResult result, { Offset position }) {
|
||||||
|
return defaultHitTestChildren(result, position: position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CustomLayoutParentData extends ContainerBoxParentData<RenderBox> {
|
||||||
|
|
||||||
|
}
|
110
lib/view.dart
110
lib/view.dart
@ -32,9 +32,29 @@ class ViewWidgetState extends State<ViewWidget> {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return ListView(
|
return ListView(
|
||||||
padding: EdgeInsets.all(0.0),
|
shrinkWrap: true,
|
||||||
//physics: const AlwaysScrollableScrollPhysics(),
|
padding: EdgeInsets.all(0),
|
||||||
children: _buildChildren(context),
|
children: <Widget>[
|
||||||
|
DynamicMultiColumnLayout(
|
||||||
|
minColumnWidth: Sizes.minViewColumnWidth,
|
||||||
|
children: _buildChildren(context),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
return ListView(
|
||||||
|
shrinkWrap: true,
|
||||||
|
padding: EdgeInsets.all(0),
|
||||||
|
children: <Widget>[
|
||||||
|
ConstrainedBox(
|
||||||
|
constraints: BoxConstraints(maxHeight: 3000),
|
||||||
|
child: CustomMultiChildLayout(
|
||||||
|
delegate: ViewLayoutBuilder(
|
||||||
|
cardsCount: widget.view.cards.length
|
||||||
|
),
|
||||||
|
children: _buildChildren(context),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -49,34 +69,27 @@ class ViewWidgetState extends State<ViewWidget> {
|
|||||||
|
|
||||||
List<Widget> _buildChildren(BuildContext context) {
|
List<Widget> _buildChildren(BuildContext context) {
|
||||||
List<Widget> result = [];
|
List<Widget> result = [];
|
||||||
|
int layoutChildId = 0;
|
||||||
|
|
||||||
if (widget.view.badges.isNotEmpty) {
|
/*if (widget.view.badges.isNotEmpty) {
|
||||||
result.insert(0,
|
result.add(
|
||||||
Wrap(
|
LayoutId(
|
||||||
alignment: WrapAlignment.center,
|
id: "badges",
|
||||||
spacing: 10.0,
|
child: Wrap(
|
||||||
runSpacing: 1.0,
|
alignment: WrapAlignment.center,
|
||||||
children: _buildBadges(context),
|
spacing: 10.0,
|
||||||
|
runSpacing: 1.0,
|
||||||
|
children: _buildBadges(context),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
List<Widget> cards = [];
|
|
||||||
widget.view.cards.forEach((HACard card){
|
widget.view.cards.forEach((HACard card){
|
||||||
cards.add(
|
result.add(
|
||||||
ConstrainedBox(
|
card.build(context)
|
||||||
constraints: BoxConstraints(maxWidth: 500),
|
|
||||||
child: card.build(context),
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
result.add(
|
|
||||||
Column (
|
|
||||||
children: cards,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +97,9 @@ class ViewWidgetState extends State<ViewWidget> {
|
|||||||
List<Widget> result = [];
|
List<Widget> result = [];
|
||||||
widget.view.badges.forEach((Entity entity) {
|
widget.view.badges.forEach((Entity entity) {
|
||||||
if (!entity.isHidden) {
|
if (!entity.isHidden) {
|
||||||
result.add(entity.buildBadgeWidget(context));
|
result.add(
|
||||||
|
entity.buildBadgeWidget(context)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
@ -95,5 +110,50 @@ class ViewWidgetState extends State<ViewWidget> {
|
|||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class ViewLayoutBuilder extends MultiChildLayoutDelegate {
|
||||||
|
final int cardsCount;
|
||||||
|
|
||||||
|
ViewLayoutBuilder({@required this.cardsCount});
|
||||||
|
|
||||||
|
@override
|
||||||
|
void performLayout(Size size) {
|
||||||
|
int columnsCount = (size.width ~/ Sizes.minViewColumnWidth);
|
||||||
|
double columnWidth = size.width / columnsCount;
|
||||||
|
List<double> columnXPositions = [];
|
||||||
|
List<double> columnYPositions = [];
|
||||||
|
double startY = 0;
|
||||||
|
if (hasChild("badges")) {
|
||||||
|
Size badgesSizes = layoutChild(
|
||||||
|
'badges', BoxConstraints.tightFor(width: size.width));
|
||||||
|
startY += badgesSizes.height;
|
||||||
|
positionChild('badges', Offset(0, 0));
|
||||||
|
}
|
||||||
|
for (int i =0; i < columnsCount; i++) {
|
||||||
|
columnXPositions.add(i*columnWidth);
|
||||||
|
columnYPositions.add(startY);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < cardsCount; i++) {
|
||||||
|
final String cardId = 'card_$i';
|
||||||
|
|
||||||
|
if (hasChild(cardId)) {
|
||||||
|
int columnToAdd = 0;
|
||||||
|
double minYPosition = columnYPositions[0];
|
||||||
|
for (int i=1; i<columnsCount; i++) {
|
||||||
|
if (columnYPositions[i] < minYPosition) {
|
||||||
|
minYPosition = columnYPositions[i];
|
||||||
|
columnToAdd = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Size newSize = layoutChild(
|
||||||
|
'$cardId', BoxConstraints.tightFor(width: columnWidth));
|
||||||
|
positionChild('$cardId', Offset(columnXPositions[columnToAdd], columnYPositions[columnToAdd]));
|
||||||
|
columnYPositions[columnToAdd] = minYPosition + newSize.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRelayout(MultiChildLayoutDelegate oldDelegate) => false;
|
||||||
}
|
}
|
@ -164,7 +164,7 @@ packages:
|
|||||||
name: flutter_webview_plugin
|
name: flutter_webview_plugin
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.7"
|
version: "0.3.8"
|
||||||
http:
|
http:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -374,7 +374,7 @@ packages:
|
|||||||
name: url_launcher
|
name: url_launcher
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.1.2"
|
version: "5.1.3"
|
||||||
uuid:
|
uuid:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
Reference in New Issue
Block a user