import 'package:flutter/material.dart'; import 'dart:convert'; import 'config.dart'; import 'package:location/location.dart'; import 'dart:async'; import 'package:http/http.dart' as http; class Ads{ String title; String image; String id; String desc; Ads({this.title,this.image,this.desc,this.id}); factory Ads.fromJson(Map json) { return Ads( title: json['title'] as String, image: json['image'] as String, id: json['id'] as String, desc: json['desc'] as String, ); } } class Offers extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Offers', theme: ThemeData( // This is the theme of your application. // // Try running your application with "flutter run". You'll see the // application has a blue toolbar. Then, without quitting the app, try // changing the primarySwatch below to Colors.green and then invoke // "hot reload" (press "r" in the console where you ran "flutter run", // or simply save your changes to "hot reload" in a Flutter IDE). // Notice that the counter didn't reset back to zero; the application // is not restarted. primarySwatch: Colors.red, ), home: OffersPage(), ); } } class OffersPage extends StatefulWidget { // This widget is the home page of your application. It is stateful, meaning // that it has a State object (defined below) that contains fields that affect // how it looks. // This class is the configuration for the state. It holds the values (in this // case the title) provided by the parent (in this case the App widget) and // used by the build method of the State. Fields in a Widget subclass are // always marked "final". @override _OffersPageState createState() => _OffersPageState(); } class _OffersPageState extends State { StreamSubscription locationSubscription; List parseAds(String responseBody) { final parsed = json.decode(responseBody).cast>(); return parsed.map((json) => Ads.fromJson(json)).toList(); } List ads; void get_ads() async { String latitude = ""; String longitude = ""; Location location = new Location(); bool _serviceEnabled; PermissionStatus _permissionGranted; _serviceEnabled = await location.serviceEnabled(); if (!_serviceEnabled) { _serviceEnabled = await location.requestService(); if (!_serviceEnabled) { return; } } _permissionGranted = await location.hasPermission(); if (_permissionGranted == PermissionStatus.denied) { _permissionGranted = await location.requestPermission(); if (_permissionGranted != PermissionStatus.granted) { return; } } await location.getLocation().then((res) { latitude = res.latitude.toString(); longitude = res.longitude.toString(); }); locationSubscription = location.onLocationChanged.listen((res) { latitude = res.latitude.toString(); longitude = res.longitude.toString(); }); if(latitude.isNotEmpty) { print("Latitude:" + latitude + " Longitude:" + longitude); var res = await http.post( new Config().ads_url(latitude, longitude)); //in query there might be unwant character so, we encode the query to url if (res.statusCode == 200) { if (mounted) { setState(() { ads = parseAds(res.body); //update data value and UI }); } } } } @override initState() { get_ads(); super.initState(); } @override Widget build(BuildContext context) { // This method is rerun every time setState is called, for instance as done // by the _incrementCounter method above. // // The Flutter framework has been optimized to make rerunning build methods // fast, so that you can just rebuild anything that needs updating rather // than having to individually change instances of widgets. return Scaffold( resizeToAvoidBottomInset:false, body: Center( // Center is a layout widget. It takes a single child and positions it // in the middle of the parent. child: Column( // Column is also a layout widget. It takes a list of children and // arranges them vertically. By default, it sizes itself to fit its // children horizontally, and tries to be as tall as its parent. // // Invoke "debug painting" (press "p" in the console, choose the // "Toggle Debug Paint" action from the Flutter Inspector in Android // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) // to see the wireframe for each widget. // // Column has various properties to control how it sizes itself and // how it positions its children. Here we use mainAxisAlignment to // center the children vertically; the main axis here is the vertical // axis because Columns are vertical (the cross axis would be // horizontal). mainAxisAlignment: MainAxisAlignment.center, children: [ show_ads(), ], ), ) , ); } @override void dispose() { locationSubscription.cancel(); super.dispose(); } Widget show_ads(){ if(ads==null){ return Expanded( child:Container( padding: EdgeInsets.all(20), child: Center(child: CircularProgressIndicator()) //if is searching then show "Please wait" //else show search peopels text )); }else if(ads.length>0) { return Expanded( child: ListView( physics: const AlwaysScrollableScrollPhysics(), children: [ Container( padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0), child: Text("SPONSORED ADS", style: TextStyle( color: Colors.black, fontWeight: FontWeight.bold, fontSize: 15, )), ), AdView(), Container( padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0), child: FlatButton( padding: EdgeInsets.all(0.0), onPressed: () { }, child: Text("Advertise", style: TextStyle( color: Colors.blue, fontWeight: FontWeight.bold, fontSize: 15, )), ) ), ], ), ); } } Widget AdView() { if(ads.length>0) { return SingleChildScrollView( physics: ScrollPhysics(), child: Column( children: [ListView.separated( separatorBuilder: (context, index) => Divider(color: Colors.grey,), padding: EdgeInsets.all(0.0), shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemCount: ads.length, itemBuilder: (BuildContext ctxt, int index) => Padding(padding: EdgeInsets.all(1.0), child: Container( padding: EdgeInsets.all(0.0), child: new Column( mainAxisSize: MainAxisSize.max, children: [ Expanded( child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment .start, mainAxisAlignment: MainAxisAlignment .spaceEvenly, children: [ FlatButton( padding: EdgeInsets.all(0.0), onPressed: () { }, child: Row( mainAxisSize: MainAxisSize.max, children: [ Container( padding: EdgeInsets.fromLTRB( 20.0, 15.0, 20.0, 15.0), child: Text(ads[index].title, style: TextStyle( color: Colors.black, fontWeight: FontWeight .bold, fontSize: 15, )), ), Container( width: MediaQuery .of(context) .size .width, height: 200, decoration: BoxDecoration( image: DecorationImage( fit: BoxFit.fill, image: NetworkImage( ads[index].image), ), ), ), ] ) ), ] ), ), ], ), ) ) ) ],),); }else{ return Container( padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0), child:Text("No sponsored adsense"), ); } } }