Skip to content

Commit

Permalink
layout improved/ progress
Browse files Browse the repository at this point in the history
  • Loading branch information
richtwin567 committed Jul 25, 2020
1 parent 84096fe commit 9a7e989
Show file tree
Hide file tree
Showing 9 changed files with 415 additions and 228 deletions.
File renamed without changes
190 changes: 190 additions & 0 deletions lib/screens/contact_screen/local_widgets/contact_detail_image.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import 'dart:async' show Future;
import 'dart:math';
import 'package:flutter/services.dart' show rootBundle;
import 'package:flutter/material.dart';

/* Future<String> extractAssetContent(String assetPath) async {
var s = await rootBundle.loadString(assetPath);
print(s); //for debug
parseSvgAssetContent(s);
return s;
}
parseSvgAssetContent(String svgContent) {
var lines = svgContent.split(new RegExp('[<,>,"]'));
lines.removeWhere((element) =>
element.isEmpty || element == '/' || element.contains('svg'));
List<String> parts = [];
lines.forEach((element) {
parts.add(element.trim());
});
int pathsStart;
Map<String, dynamic> properties = {};
for (var i = 0; i < parts.length - 2; i += 2) {
if (!parts[i].contains('path')) {
properties
.addAll({parts[i].substring(0, parts[i].length - 1): parts[i + 1]});
} else {
properties.addAll({
'path': [
{'d': parts[i + 1], 'commands': []}
]
});
pathsStart = i + 2;
break;
}
}
int pathNum = 0;
for (var x = pathsStart; x < parts.length; x += 2) {
if (!parts[x].contains('path')) {
properties['path'][pathNum]
.addAll({parts[x].substring(0, parts[x].length - 1): parts[x + 1]});
} else {
pathNum++;
properties['path'].add({'d': parts[x + 1], 'commands': []});
}
}
for (var i = 0; i < properties['path'].length; i++) {
int startCommand;
int endCommand;
String commandsString = properties['path'][i]['d'];
int length = commandsString.length;
//print('full string - ' + commandsString + ' - $length');
for (var x = 0; x < commandsString.length; x++) {
if (commandsString[x].contains(new RegExp('[a-zA-Z]'))) {
startCommand = x;
//print('start - ' + commandsString[startCommand] + ' - $startCommand');
if (startCommand + 1 < commandsString.length) {
for (var p = startCommand + 1; p < commandsString.length; p++) {
if (commandsString[p].contains(new RegExp('[a-zA-Z]'))) {
endCommand = p;
//print('end - ' + commandsString[endCommand] + ' - $endCommand');
//print(commandsString.substring(startCommand, endCommand));
properties['path'][i]['commands']
.add(commandsString.substring(startCommand, endCommand));
//print(properties['path'][i]['commands']);
break;
}
}
} else {
properties['path'][i]['commands']
.add(commandsString[commandsString.length - 1]);
}
}
}
}
//print(properties);
//return properties;
}
*/
class VerticalPoint<T extends num> extends Point<T> {
VerticalPoint(num y, [num x]) : super(x, y);
}

class HorizontalPoint<T extends num> extends Point<T> {
HorizontalPoint(num x, [num y]) : super(x, y);
}

class MovePoint<T extends num> extends Point<T> {
MovePoint(T x, T y) : super(x, y);
}

class CurvePoints<T extends num> extends Point<T> {
final num x2;
final num y2;
final num x3;
final num y3;
CurvePoints(num x1, num y1, this.x2, this.y2, this.x3, this.y3)
: super(x1, y1);
}


class ContactDetailSvg extends CustomPainter {
List<Point<double>> path1 = [
MovePoint(0.0, 0.0),
HorizontalPoint(24.0, 0.0),
VerticalPoint(24.0, 0.0),
HorizontalPoint(-24.0, 0.0)
];

List<Point<double>> path2 = [
MovePoint(12.0, 12.0),
CurvePoints(0.0, 0.0, 3.8, 0.0, 4.0, -4.0),
CurvePoints(0.0, 0.0, 0.0, -3.8, -4.0, -4.0),
CurvePoints(0.0, 0.0, -3.8, 0.0, -4.0, 4.0),
CurvePoints(0.0, 0.0, 0.0, 3.8, 4.0, 4.0),
];

List<Point<double>> path3 = [
MovePoint(12.0, 14.0),
CurvePoints(-2.67, 0.0, -8.0, 1.34, -8.0, 4.0),
VerticalPoint(2.0, 0.0),
HorizontalPoint(16.0, 0.0),
VerticalPoint(-2.0, 0.0),
CurvePoints(0.0, -2.66, -5.33, -4.0, -8.0, -4.0)
];

double scale;
double offsetX;
double offsetY;
Color color;

ContactDetailSvg(
{@required this.color,
this.scale = 1.0,
this.offsetX = 0.0,
this.offsetY = 0.0})
: super();

drawPathFromPoints(Canvas canvas, Paint paint, List<Point> points) {
Path path = Path();
points.forEach((p) {
if (p is MovePoint) {
p = MovePoint(offsetX + (p.x * scale), offsetY + (p.y * scale));
path.moveTo(p.x, p.y);
} else if (p is VerticalPoint) {
p = VerticalPoint(p.y * scale, (p.x * scale));
path.relativeLineTo(p.x, p.y);
} else if (p is HorizontalPoint) {
p = HorizontalPoint((p.x * scale), (p.y * scale));
path.relativeLineTo(p.x, p.y);
} else {
CurvePoints cp = p as CurvePoints;
cp = CurvePoints((cp.x * scale), (cp.y * scale), (cp.x2 * scale),
(cp.y2 * scale), (cp.x3 * scale), (cp.y3 * scale));
path.relativeCubicTo(cp.x, cp.y, cp.x2, cp.y2, cp.x3, cp.y3);
}
});
canvas.drawPath(path, paint);
}

@override
void paint(Canvas canvas, Size size) {
Paint path1Paint = Paint();
path1Paint..color = Color.fromRGBO(0, 0, 0, 0);

Paint path2Paint = Paint();
path2Paint
..color = color
..style = PaintingStyle.fill;

Paint path3Paint = Paint();
path3Paint
..color = color
..style = PaintingStyle.fill;

drawPathFromPoints(canvas, path1Paint, path1);
canvas.drawCircle(Offset((12.0*scale)+offsetX, (8.0*scale)+offsetY), 4.0*scale, path2Paint);
drawPathFromPoints(canvas, path3Paint, path3);
}

@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}
76 changes: 76 additions & 0 deletions lib/screens/contact_screen/local_widgets/contact_widgets.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import 'package:flutter/material.dart';

/// A [Card] that is standardized for the contact pages
class ContactCard extends Card {
/// Required widget that should go inside the card
final Widget child;

/// The space around the contact card
///
/// default if no margin is specified:
///
/// ```
/// this.margin = const EdgeInsets.fromLTRB(2.0, 5.0, 2.0, 5.0)
/// ```
final EdgeInsetsGeometry margin;

/// Creates a Contact card with a [margin] around it and has
/// the specified [child] inside the card.
ContactCard(
{Key key,
@required this.child,
this.margin = const EdgeInsets.fromLTRB(2.0, 5.0, 2.0, 5.0)})
: super(
shape: Border(),
key: key,
child: child,
elevation: 2,
margin: margin);
} // ContactCard defintion

/// A [ListTile] wrapped in a [ContactCard] that
/// allows navigation to the [ContactDetailPage] for this [ContactTile] when tapped.
class ContactTile extends StatelessWidget {
/// The title of this ContactTile.
final String title;

/// The subtitle for this ContactTile.
final String subtitle;

/// The route to the page that the Navigator should push when this tile is tapped.
/// Must be a named route.
final String namedRoute;

/// The data to be passed to the next page when this tile is tapped
final dynamic arguments;

/// Creates a contact tile.
///
/// A contact tile has a [title] and [subtitle].
/// When tapped, this tile will navigate to the page defined by the [namedRoute]
/// and pass its [arguments], if given, to that page.
/// The [arguments] would be the information for this contact.
ContactTile(
{Key key,
@required this.title,
@required this.subtitle,
@required this.namedRoute,
this.arguments})
: super(key: key);

@override
Widget build(BuildContext context) {
return ContactCard(
child: ListTile(
contentPadding: EdgeInsets.fromLTRB(16.0, 10.0, 16.0, 10.0),
onTap: () {
arguments != null
? Navigator.pushNamed(context, namedRoute, arguments: arguments)
: Navigator.pushNamed(context, namedRoute);
},
title: Text(title),
subtitle: Text(subtitle),
trailing: Icon(Icons.chevron_right),
));
}
} // ContactTile definition
45 changes: 28 additions & 17 deletions lib/screens/contact_screen/pages/contact_detail_page.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:fst_app_flutter/screens/contact_screen/pages/contacts_page_general.dart';
import 'package:fst_app_flutter/screens/contact_screen/local_widgets/contact_widgets.dart';
import 'package:fst_app_flutter/utils/open_url.dart';
import 'package:fst_app_flutter/screens/contact_screen/local_widgets/contact_detail_image.dart';

class ContactDetailPage extends StatelessWidget {
static const routeName = '/contactDetail';
Expand All @@ -9,7 +11,12 @@ class ContactDetailPage extends StatelessWidget {
final dynamic contactDetails = ModalRoute.of(context).settings.arguments;
final ContactCard contactMethods = _contactDetailList(contactDetails);
final ContactCard contactInfo = _aboutContactList(contactDetails);

final mq = MediaQuery.of(context);
print(mq.size.height / 2);
print(mq.size.width / 2);
print(mq.size.aspectRatio);
print(mq.devicePixelRatio);
print(mq);

return Scaffold(
body: CustomScrollView(
Expand All @@ -23,22 +30,22 @@ class ContactDetailPage extends StatelessWidget {
floating: false,
pinned: true,
snap: false,
expandedHeight: 200.0,
expandedHeight: mq.size.height/3.5 ,
flexibleSpace: FlexibleSpaceBar(
/* background: SvgPicture.asset(
'assets/images/person-white-48dp.svg',
fit: BoxFit.contain,
color: Colors.blue[800],
alignment: Alignment.center,
), */
background: CustomPaint(
painter: ContactDetailSvg(
offsetX: mq.size.width / mq.devicePixelRatio,
offsetY: (mq.size.height/mq.devicePixelRatio)/3.5,
scale: (mq.devicePixelRatio/ mq.size.aspectRatio),
color: Colors.blue[800])),
title: Padding(
padding: EdgeInsets.only(right: 50.0),
child: Text(
contactDetails['name'],
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
))),
padding: EdgeInsets.only(right: 70.0),
child: Text(
contactDetails['name'],
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
))),
SliverFillRemaining(
child: Column(
mainAxisSize: MainAxisSize.max,
Expand All @@ -61,7 +68,9 @@ class ContactDetailPage extends StatelessWidget {
Icon icon =
i == 0 ? Icon(Icons.phone) : Icon(Icons.phone, color: Colors.white);
return ListTile(
leading: icon, title: Text(data['phone_contact_set'][i]['phone']));
leading: icon,
onTap: () => openUrl('tel:' + data['phone_contact_set'][i]['phone']),
title: Text(data['phone_contact_set'][i]['phone']));
});

List<dynamic> iconifiedList = [
Expand All @@ -71,6 +80,7 @@ class ContactDetailPage extends StatelessWidget {
? ListTile(
leading: Icon(Icons.email),
title: Text(data['email']),
onTap: () => openUrl('mailto:' + data['email']),
)
: null,
data['fax'] != '' ? Divider() : null,
Expand Down Expand Up @@ -104,6 +114,7 @@ class ContactDetailPage extends StatelessWidget {
data['website'] != '' ? Divider() : null,
data['website'] != ''
? ListTile(
onTap: () => openUrl(data['website']),
title: Text('Website'),
subtitle: Text(data['website']),
trailing: Icon(Icons.chevron_right),
Expand Down
Loading

0 comments on commit 9a7e989

Please sign in to comment.