Skip to content

Commit af6be48

Browse files
committed
Fixed #13
1 parent e1c909f commit af6be48

File tree

6 files changed

+187
-182
lines changed

6 files changed

+187
-182
lines changed

lib/CustomImageSearchPage.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class CustomImageSearchDemo extends StatefulWidget {
1010

1111
class _CustomImageSearchDemoState extends State<CustomImageSearchDemo> {
1212
final CustomSearchSearchDelegate _delegate =
13-
CustomSearchSearchDelegate.fakeStaticSource();
13+
CustomSearchSearchDelegate.fakeStaticSourceImageSearch();
1414

1515
// final CustomSearchSearchDelegate _delegate =
1616
// new CustomSearchSearchDelegate.imageSearch(
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:flutter_app_cse/search_data_source.dart';
3+
import 'package:url_launcher/url_launcher.dart';
4+
5+
class ImageSearchResultCard extends StatelessWidget {
6+
ImageSearchResultCard({@required this.searchResult});
7+
8+
final SearchResult searchResult;
9+
10+
@override
11+
Widget build(BuildContext context) {
12+
return GestureDetector(
13+
onTap: () async {
14+
if (await canLaunch(searchResult.result.image.contextLink)) {
15+
await launch(searchResult.result.image.contextLink);
16+
}
17+
},
18+
child: GridTile(
19+
child: Image.network(this.searchResult.result.link, fit: BoxFit.cover),
20+
footer: GridTileBar(
21+
backgroundColor: Colors.black45,
22+
title: FittedBox(
23+
fit: BoxFit.scaleDown,
24+
alignment: Alignment.centerLeft,
25+
child: Text(this.searchResult.result.title),
26+
)),
27+
),
28+
);
29+
}
30+
}
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:flutter_app_cse/shared_constant.dart';
3+
import 'package:flutter_app_cse/search_data_source.dart';
4+
import 'package:url_launcher/url_launcher.dart';
5+
6+
class WebSearchResultCard extends StatelessWidget {
7+
const WebSearchResultCard(
8+
{@required this.searchResult,
9+
this.webSearchLayout = WebSearchLayout.CSE});
10+
11+
final SearchResult searchResult;
12+
final WebSearchLayout webSearchLayout;
13+
14+
Widget _generateTitleTile(BuildContext context) {
15+
final ThemeData theme = Theme.of(context);
16+
return ListTile(
17+
title: Padding(
18+
padding: EdgeInsets.only(top: 6.0),
19+
child: Text(
20+
this.searchResult.result.title,
21+
style: theme.textTheme.headline.copyWith(
22+
fontSize: 15.0, fontWeight: FontWeight.bold, color: Colors.blue),
23+
),
24+
),
25+
subtitle: new Text(
26+
this.searchResult.result.link,
27+
style:
28+
theme.textTheme.body1.copyWith(fontSize: 14.0, color: Colors.green),
29+
),
30+
);
31+
}
32+
33+
Widget _generateBodyTile(BuildContext context) {
34+
final ThemeData theme = Theme.of(context);
35+
bool haveThumbnail = this.searchResult.result.pagemap['thumbnail'] != null;
36+
if (!haveThumbnail) {
37+
return Container(
38+
padding: const EdgeInsets.only(
39+
left: 14.0,
40+
bottom: 8.0,
41+
),
42+
child: Container(
43+
padding: const EdgeInsets.only(right: 10.0),
44+
child: Text(
45+
this.searchResult.result.snippet,
46+
style: theme.textTheme.body1,
47+
textAlign: TextAlign.left,
48+
)),
49+
);
50+
} else {
51+
return Container(
52+
padding: const EdgeInsets.only(
53+
left: 15.0,
54+
bottom: 8.0,
55+
),
56+
child: new Row(children: [
57+
Image.network(
58+
this.searchResult.result.pagemap['thumbnail'][0]['src']),
59+
Expanded(
60+
child: Container(
61+
padding: const EdgeInsets.only(left: 10.0, right: 12.0),
62+
child: Text(
63+
this.searchResult.result.snippet,
64+
style: theme.textTheme.body1,
65+
textAlign: TextAlign.left,
66+
))),
67+
]),
68+
);
69+
}
70+
}
71+
72+
Widget _buildSimpleLayout(BuildContext context) {
73+
final ThemeData theme = Theme.of(context);
74+
return new Card(
75+
child: new Padding(
76+
padding: const EdgeInsets.all(8.0),
77+
child: new ListTile(
78+
leading: this.searchResult.result.pagemap['thumbnail'] != null
79+
? new Image.network(
80+
this.searchResult.result.pagemap['thumbnail'][0]['src'])
81+
: null,
82+
title: new Text(
83+
this.searchResult.result.title,
84+
style: theme.textTheme.headline
85+
.copyWith(fontSize: 12.0, fontWeight: FontWeight.bold),
86+
),
87+
subtitle: new Text(
88+
this.searchResult.result.snippet,
89+
style: theme.textTheme.body1.copyWith(fontSize: 12.0),
90+
),
91+
),
92+
));
93+
}
94+
95+
Widget _buildCSELayout(BuildContext context) {
96+
return new Container(
97+
decoration: new BoxDecoration(boxShadow: [
98+
new BoxShadow(
99+
color: Colors.grey,
100+
blurRadius: 1.0,
101+
),
102+
]),
103+
child: new Card(
104+
child: Column(
105+
children: [
106+
_generateTitleTile(context),
107+
new Divider(color: Colors.black26),
108+
_generateBodyTile(context),
109+
],
110+
),
111+
),
112+
);
113+
}
114+
115+
Widget _buildFromLayout(BuildContext context) {
116+
switch (this.webSearchLayout) {
117+
case WebSearchLayout.simple:
118+
return _buildSimpleLayout(context);
119+
case WebSearchLayout.CSE:
120+
return _buildCSELayout(context);
121+
default:
122+
return new Text('Invalid Layout For WebSearchResult!');
123+
}
124+
}
125+
126+
@override
127+
Widget build(BuildContext context) {
128+
return new GestureDetector(
129+
onTap: () async {
130+
if (await canLaunch(searchResult.result.link)) {
131+
await launch(searchResult.result.link);
132+
}
133+
},
134+
child: _buildFromLayout(context));
135+
}
136+
}

lib/search_data_source.dart

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import "package:googleapis_auth/auth_io.dart" as auth;
99
import 'package:googleapis/customsearch/v1.dart' as customsearch;
1010
import 'package:english_words/english_words.dart';
1111

12+
import 'shared_constant.dart';
13+
1214
/// A wrapper class for [customsearch.Result].
1315
/// [SearchResult] will use the landing page link to measure if two results are
1416
/// the same. This is useful for deduplicating image search result.
@@ -73,8 +75,10 @@ class SearchResults {
7375
SearchResults.empty();
7476

7577
SearchResults(customsearch.Search search) {
78+
var results = new List<SearchResult>();
7679
search.items.forEach((item) =>
77-
searchResults.add(SearchResult.escapeLineBreakInSnippet(item)));
80+
results.add(SearchResult.escapeLineBreakInSnippet(item)));
81+
this.searchResults = Set<SearchResult>.from(results).toList();
7882
}
7983
}
8084

@@ -97,7 +101,7 @@ class FakeSearchDataSource implements SearchDataSource {
97101
'web': _StaticSearchResponse(
98102
assetPath: 'res/sampledata/nytimes_sample_data.json'),
99103
'image': _StaticSearchResponse(
100-
assetPath: 'res/sampledata/nytimes_sample_data.json',
104+
assetPath: 'res/sampledata/nytimes_image_sample_data.json',
101105
searchType: 'image'),
102106
'promotion': _StaticSearchResponse(
103107
assetPath: 'res/sampledata/nytimes_with_promotion.json'),
@@ -147,8 +151,6 @@ class CustomSearchDataSource implements SearchDataSource {
147151
}
148152
customsearch.Search search =
149153
await this.api.cse.list(query, cx: this.cx, searchType: searchType);
150-
searchCount += 1;
151-
print("search count: $searchCount");
152154
return SearchResults(search);
153155
}
154156
}

0 commit comments

Comments
 (0)