refactor: table view

This commit is contained in:
Rongjian Zhang 2019-09-14 23:48:01 +08:00
parent 8cd1d9f1a5
commit 124ec611ad
10 changed files with 140 additions and 162 deletions

View File

@ -139,7 +139,7 @@ class _ListScaffoldState<T, K> extends State<ListScaffold<T, K>> {
}
if (index % 2 == 1) {
return BorderView(height: 1);
return borderView;
}
return widget.itemBuilder(items[index ~/ 2]);

View File

@ -103,7 +103,7 @@ class _LongListScaffoldState<T, K> extends State<LongListScaffold<T, K>> {
Widget _buildItem(BuildContext context, int index) {
if (index % 2 == 1) {
return BorderView();
return borderView;
}
int realIndex = index ~/ 2;

View File

@ -393,7 +393,7 @@ mutation {
],
),
),
BorderView(),
borderView,
],
);
},

View File

@ -94,7 +94,7 @@ class ObjectScreen extends StatelessWidget {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: join(
BorderView(),
borderView,
entries.map((item) {
return Link(
screenBuilder: item['type'] == 'commit'

View File

@ -174,7 +174,7 @@ class RepoScreen extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
RepoItem(payload, inRepoScreen: true),
BorderView(),
borderView,
Row(
children: <Widget>[
EntryItem(
@ -202,7 +202,7 @@ class RepoScreen extends StatelessWidget {
),
],
),
BorderView(height: 10),
borderView10,
Padding(
padding: const EdgeInsets.all(_languageBarPadding),
child: ClipRRect(
@ -224,16 +224,8 @@ class RepoScreen extends StatelessWidget {
TableViewItem(
leftWidget: Icon(Octicons.code, size: 20),
text: Text('Code'),
rightWidget: Row(
children: <Widget>[
rightWidget:
Text(filesize(payload['languages']['totalSize'] as int)),
Icon(
CupertinoIcons.right_chevron,
size: 18,
color: PrimerColors.gray300,
),
],
),
screenBuilder: (_) => ObjectScreen(
owner: owner,
name: name,
@ -243,52 +235,27 @@ class RepoScreen extends StatelessWidget {
TableViewItem(
leftWidget: Icon(Octicons.issue_opened, size: 20),
text: Text('Issues'),
rightWidget: Row(
children: <Widget>[
rightWidget:
Text(numberFormat.format(payload['issues']['totalCount'])),
Icon(
CupertinoIcons.right_chevron,
size: 18,
color: PrimerColors.gray300,
),
],
),
screenBuilder: (_) => IssuesScreen(owner: owner, name: name),
),
TableViewItem(
leftWidget: Icon(Octicons.git_pull_request, size: 20),
text: Text('Pull requests'),
rightWidget: Row(
children: <Widget>[
Text(numberFormat
.format(payload['pullRequests']['totalCount'])),
Icon(
CupertinoIcons.right_chevron,
size: 18,
color: PrimerColors.gray300,
),
],
),
rightWidget: Text(
numberFormat.format(payload['pullRequests']['totalCount'])),
screenBuilder: (_) =>
IssuesScreen(owner: owner, name: name, isPullRequest: true),
),
]),
BorderView(height: 10),
borderView10,
TableView(items: [
TableViewItem(
leftWidget: Icon(Octicons.history, size: 20),
text: Text('Commits'),
rightWidget: Row(
children: <Widget>[
Text(numberFormat.format(payload['defaultBranchRef']
['target']['history']['totalCount'])),
Icon(
CupertinoIcons.right_chevron,
size: 18,
color: PrimerColors.gray300,
),
],
),
rightWidget: Text(numberFormat.format(
payload['defaultBranchRef']['target']['history']
['totalCount'])),
screenBuilder: (_) => CommitsScreen(owner, name),
),
TableViewItem(
@ -300,7 +267,7 @@ class RepoScreen extends StatelessWidget {
payload['licenseInfo']['name'])),
),
]),
BorderView(height: 10),
borderView10,
if (payload['object'] != null)
Container(
padding: EdgeInsets.all(16),

View File

@ -11,15 +11,10 @@ import '../widgets/table_view.dart';
import '../screens/repo.dart';
import '../screens/login.dart';
class SettingsScreen extends StatefulWidget {
@override
_SettingsScreenState createState() => _SettingsScreenState();
}
class _SettingsScreenState extends State<SettingsScreen> {
class SettingsScreen extends StatelessWidget {
Widget _buildRightWidget(bool checked) {
if (!checked) return null;
return Icon(Octicons.check, color: CupertinoColors.activeBlue, size: 20);
return Icon(Octicons.check, color: CupertinoColors.activeBlue, size: 24);
}
@override
@ -41,7 +36,8 @@ class _SettingsScreenState extends State<SettingsScreen> {
TableViewSeperator(),
TableView(headerText: 'THEME', items: [
TableViewItem(
text: Text('material'),
leftIconData: MaterialCommunityIcons.material_design,
text: Text('Material'),
rightWidget:
_buildRightWidget(themeProvider.theme == ThemeMap.material),
onTap: () {
@ -49,9 +45,11 @@ class _SettingsScreenState extends State<SettingsScreen> {
themeProvider.setTheme(ThemeMap.material);
}
},
hideRightChevron: true,
),
TableViewItem(
text: Text('cupertino'),
leftIconData: MaterialCommunityIcons.apple,
text: Text('Cupertino'),
rightWidget: _buildRightWidget(
themeProvider.theme == ThemeMap.cupertino),
onTap: () {
@ -59,38 +57,36 @@ class _SettingsScreenState extends State<SettingsScreen> {
themeProvider.setTheme(ThemeMap.cupertino);
}
},
hideRightChevron: true,
),
]),
TableViewSeperator(),
TableView(headerText: 'REVIEW', items: [
TableView(headerText: 'ABOUT', items: [
TableViewItem(
text: Text('Review'),
leftIconData: Octicons.repo,
text: Text('pd4d10/git-touch'),
screenBuilder: (_) => RepoScreen('pd4d10', 'git-touch'),
),
TableViewItem(
leftIconData: Octicons.star,
text: Text('Rate this App'),
onTap: () {
LaunchReview.launch(
androidAppId: 'io.github.pd4d10.gittouch',
iOSAppId: '1452042346',
);
},
)
]),
TableViewSeperator(),
TableView(headerText: 'SOURCE CODE', items: [
),
TableViewItem(
text: Text('pd4d10/git-touch'),
screenBuilder: (_) => RepoScreen('pd4d10', 'git-touch'),
)
]),
TableViewSeperator(),
TableView(headerText: 'LICENSE', items: [
TableViewItem(
text: Text('MIT'),
leftIconData: Octicons.law,
text: Text('License'),
rightWidget: Text('MIT'),
onTap: () {
launch(
'https://github.com/pd4d10/git-touch/blob/master/LICENSE');
},
)
]),
TableViewSeperator(),
],
);
},

View File

@ -48,7 +48,7 @@ class _TrendingScreenState extends State<TrendingScreen> {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: join(
BorderView(),
borderView,
payload.map<Widget>((item) => RepoItem(item)).toList(),
),
);

View File

@ -85,10 +85,10 @@ class UserScreen extends StatelessWidget {
if (items.isEmpty) return [];
return [
BorderView(height: 10),
borderView10,
// Text('Pinned repositories'),
...join(
BorderView(),
borderView,
items.map((item) {
return RepoItem(item);
}).toList(),
@ -96,25 +96,6 @@ class UserScreen extends StatelessWidget {
];
}
TableViewItem _buildTableViewItem({
IconData iconData,
String text,
Function onTap,
}) {
if (text == null || text.isEmpty) return null;
var leftWidget = Icon(iconData, size: 20, color: PrimerColors.blue500);
return TableViewItem(
leftWidget: leftWidget,
text: Text(text),
rightWidget: onTap == null
? null
: Icon(CupertinoIcons.right_chevron,
size: 18, color: PrimerColors.gray300),
onTap: onTap,
);
}
Widget _buildContributions(List<ContributionsInfo> contributions) {
var row = Row(
children: <Widget>[],
@ -224,7 +205,7 @@ class UserScreen extends StatelessWidget {
bio: payload['bio'],
),
),
BorderView(),
borderView,
Row(children: <Widget>[
EntryItem(
count: payload['repositories']['totalCount'],
@ -250,46 +231,45 @@ class UserScreen extends StatelessWidget {
login: login, type: UsersScreenType.userFollowing),
),
]),
BorderView(height: 10),
borderView10,
_buildContributions(contributions),
BorderView(height: 10),
borderView10,
TableView(items: [
_buildTableViewItem(
iconData: Octicons.organization,
text: payload['company'],
),
_buildTableViewItem(
iconData: Octicons.location,
text: payload['location'],
onTap: payload['location'] == null
? null
: () {
launch('https://www.google.com/maps/place/' +
(payload['location'] as String)
.replaceAll(RegExp(r'\s+'), ''));
}),
_buildTableViewItem(
iconData: Octicons.mail,
text: payload['email'],
onTap: (payload['email'] as String).isEmpty
? null
: () {
launch('mailto:' + payload['email']);
},
),
_buildTableViewItem(
iconData: Octicons.link,
text: payload['websiteUrl'],
onTap: payload['websiteUrl'] == null
? null
: () {
var url = payload['websiteUrl'] as String;
if (!url.startsWith('http')) {
url = 'http://$url';
}
launch(url);
},
),
if (isNotNullOrEmpty(payload['company']))
TableViewItem(
leftIconData: Octicons.organization,
text: Text(payload['company']),
),
if (isNotNullOrEmpty(payload['location']))
TableViewItem(
leftIconData: Octicons.location,
text: Text(payload['location']),
onTap: () {
launch('https://www.google.com/maps/place/' +
(payload['location'] as String)
.replaceAll(RegExp(r'\s+'), ''));
},
),
if (isNotNullOrEmpty(payload['email']))
TableViewItem(
leftIconData: Octicons.mail,
text: Text(payload['email']),
onTap: () {
launch('mailto:' + payload['email']);
},
),
if (isNotNullOrEmpty(payload['websiteUrl']))
TableViewItem(
leftIconData: Octicons.link,
text: Text(payload['websiteUrl']),
onTap: () {
var url = payload['websiteUrl'] as String;
if (!url.startsWith('http')) {
url = 'http://$url';
}
launch(url);
},
),
]),
..._buildRepos(payload),
],

View File

@ -136,18 +136,38 @@ List<T> joinAll<T>(T seperator, List<List<T>> xss) {
final numberFormat = NumberFormat();
bool isNotNullOrEmpty(String text) {
return text != null && text.isNotEmpty;
}
class BorderView extends StatelessWidget {
final double height;
final Color color;
final double leftPadding;
BorderView({this.height = 1});
const BorderView({
this.height = 1,
this.color = PrimerColors.gray200,
this.leftPadding = 0,
});
@override
Widget build(BuildContext context) {
return SizedBox(
height: height,
child: const DecoratedBox(
decoration: const BoxDecoration(color: PrimerColors.gray100),
),
return Row(
children: <Widget>[
SizedBox(width: leftPadding),
Expanded(
child: SizedBox(
height: height,
child: DecoratedBox(
decoration: BoxDecoration(color: color),
),
),
),
],
);
}
}
const borderView = BorderView();
const borderView10 = BorderView(height: 20, color: PrimerColors.gray100);

View File

@ -16,18 +16,22 @@ class TableViewSeperator extends StatelessWidget {
class TableViewItem {
final Widget text;
final IconData leftIconData;
final Widget leftWidget;
final Widget rightWidget;
final void Function() onTap;
final WidgetBuilder screenBuilder;
final bool hideRightChevron;
TableViewItem({
this.text,
this.leftIconData,
this.leftWidget,
this.rightWidget,
this.onTap,
this.screenBuilder,
});
this.hideRightChevron = false,
}) : assert(leftIconData == null || leftWidget == null);
}
class TableView extends StatelessWidget {
@ -36,29 +40,40 @@ class TableView extends StatelessWidget {
TableView({this.headerText, @required this.items});
static final _border = BorderView();
static final _seperator = BorderView();
Widget _buildItem(TableViewItem item) {
if (item == null) return null;
var widget = Container(
height: 44,
child: Row(children: [
if (item.leftWidget != null) ...[
var widget = DefaultTextStyle(
style: TextStyle(fontSize: 16, color: PrimerColors.gray900),
overflow: TextOverflow.ellipsis,
child: Container(
height: 44,
child: Row(children: [
if (item.leftIconData != null) ...[
SizedBox(width: 12),
Icon(item.leftIconData),
// Container(
// width: 24,
// height: 24,
// // decoration: BoxDecoration(
// // borderRadius: BorderRadius.circular(4), color: PrimerColors.blue400),
// child: Icon(iconData, size: 24, color: PrimerColors.gray600),
// )
],
if (item.leftWidget != null) ...[
SizedBox(width: 12),
item.leftWidget,
],
SizedBox(width: 12),
item.leftWidget,
],
SizedBox(width: 12),
Expanded(
child: DefaultTextStyle(
child: item.text,
style: TextStyle(fontSize: 16, color: PrimerColors.gray900),
),
),
if (item.rightWidget != null) item.rightWidget,
SizedBox(width: 12),
]),
Expanded(child: item.text),
if (item.rightWidget != null) item.rightWidget,
if ((item.onTap != null || item.screenBuilder != null) &
!item.hideRightChevron)
Icon(CupertinoIcons.right_chevron,
size: 24, color: PrimerColors.gray400),
SizedBox(width: 4),
]),
),
);
if (item.onTap == null && item.screenBuilder == null) {
@ -85,9 +100,9 @@ class TableView extends StatelessWidget {
style: TextStyle(color: PrimerColors.gray600, fontSize: 13),
),
),
_border,
...join(_seperator, items.map(_buildItem).toList()),
_border,
borderView,
...join(BorderView(leftPadding: 44), items.map(_buildItem).toList()),
borderView,
],
);
}