
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'components/category.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
const String html = '''
<!DOCTYPE html>
<html lang="en">
<script type="text/javascript">
function pj1715(result){channel && channel.postMessage(JSON.stringify(result));}
</script>
<script type="text/javascript" src="https:
</html>
''';
class _MyHomePageState extends State<MyHomePage> {
late List<Map<String, dynamic>> listJson = [];
late List<Category> listClass = [];
late List<Level1words> level1wordsList = [];
late WebViewController controller = WebViewController();
late int selected = 0;
ScrollController scrollLeftController = ScrollController(),
scrollRightController = ScrollController();
@override
initState() {
super.initState();
controller
..setJavaScriptMode(JavaScriptMode.unrestricted)
..loadHtmlString(html)
..addJavaScriptChannel('channel',
onMessageReceived: (JavaScriptMessage message) {
listJson = json
.decode(message.message)['keywordAreas']
.cast<Map<String, dynamic>>();
setState(() {
listClass = List.generate(
listJson.length, (index) => Category.fromJson(listJson[index]));
level1wordsList = listClass[0].level1words;
});
});
}
@override
void dispose() {
super.dispose();
controller.removeJavaScriptChannel('channel');
scrollLeftController.dispose();
scrollRightController.dispose();
}
Widget gridWidget(List<Level2words> list) {
return GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3, mainAxisSpacing: 10, childAspectRatio: 1
),
itemBuilder: (BuildContext context, int i) {
return GestureDetector(
onTap: () {
print(list[i].url);
},
child: Column(
children: [
FadeInImage.assetNetwork(
width: 70,
height: 70,
fit: BoxFit.fitHeight,
fadeInDuration: const Duration(milliseconds: 250),
placeholder: 'images/categorydef.png',
image: 'https:${list[i].imageUrl}'),
Container(
margin: const EdgeInsets.only(top: 2),
child: Text(
list[i].keyword,
style: const TextStyle(
fontSize: 12, color: Color(0xff333333)),
),
)
],
));
},
itemCount: list.length);
}
Widget showRightWidget(List<Level1words> list) {
return ListView.builder(
controller: scrollRightController,
itemBuilder: (BuildContext context, int i) {
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text(list[i].keyword,
style: const TextStyle(
fontSize: 14,
color: Color(0xff333333),
fontWeight: FontWeight.w700)),
Container(
margin: const EdgeInsets.only(top: 9),
padding:
const EdgeInsets.only(top: 7, left: 10, right: 10, bottom: 0),
child: gridWidget(list[i].level2words))
]);
},
itemCount: list.length,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
child: Row(
children: [
Container(
width: 86,
color: const Color(0xfff8f8f8),
child: ListView.builder(
controller: scrollLeftController,
itemBuilder: (BuildContext context, int i) {
return GestureDetector(
onTap: () {
setState(() {
selected = i;
scrollLeftController.animateTo(i * 46,
duration: const Duration(milliseconds: 200),
curve: Curves.linear);
level1wordsList = listClass[i].level1words;
scrollRightController.jumpTo(0);
});
},
child: Container(
alignment: Alignment.centerLeft,
child: Container(
width: 85,
height: 46,
alignment: Alignment.center,
color: selected == i
? Colors.white
: const Color(0xfff8f8f8),
child: Text(
listClass[i].areaName,
style: TextStyle(
fontSize: 14,
color: selected == i
? const Color(0xffe93b3d)
: const Color(0xff333333)),
),
)));
},
itemCount: listClass.length),
),
Expanded(
child: Container(
height: double.infinity,
padding: const EdgeInsets.only(
top: 19, left: 7, right: 7, bottom: 0),
child: listClass.isNotEmpty
? showRightWidget(level1wordsList)
: null,
))
],
),
));
}
}
category.dart
class Category {
late String areaName
late List<Level1words> level1words
Category.fromJson(Map<String, dynamic> json) {
areaName = json['areaName']
if (json['level1words'] != null) {
level1words = <Level1words>[]
json['level1words'].forEach((v) {
level1words.add(Level1words.fromJson(v))
})
}
}
}
class Level1words {
late String keyword
late List<Level2words> level2words
Level1words.fromJson(Map<String, dynamic> json) {
keyword = json['keyword']
if (json['level2words'] != null) {
level2words = <Level2words>[]
json['level2words'].forEach((v) {
level2words.add( Level2words.fromJson(v))
})
}
}
}
class Level2words {
late String keyword
late String imageUrl
late String url
Level2words.fromJson(Map<String, dynamic> json) {
keyword = json['keyword']
imageUrl = json['imageUrl']
url = json['url']
}
}