安卓各版本和 sdk的对应关系
Flutter widget examples
- Text
1 2 3 4 5 6 7 8 |
Text( 'content', textAlign: TextAlign.left, style: TextStyle( fontWeight: FontWeight.w600, fontSize: 22, ), ), |
- 圆角raisebutton
1 2 3 4 5 6 7 8 9 10 11 |
RaisedButton( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.0), //side: BorderSide(color: Colors.red) ), padding: const EdgeInsets.all(8.0), textColor: Colors.white, color: Colors.green, onPressed: _goMain, child: new Text("Get Started"), ), |
- 带后退箭头的appbar
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
appBar: AppBar( leading: IconButton( icon: Icon(Icons.arrow_back, color: Colors.black), onPressed: () => Navigator.of(context).pop(), ), title: Text( 'Sign In', style: TextStyle( color: Colors.grey[800], ), ), centerTitle: true, backgroundColor: Colors.green, ), |
- 用户名,密码输入框
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
TextFormField( keyboardType: TextInputType.text, decoration: InputDecoration( enabledBorder: OutlineInputBorder( borderSide: BorderSide( color: Colors.indigo, width: 1.5, style: BorderStyle.solid, ), borderRadius: BorderRadius.all( Radius.circular( 15.0, ), ), ), focusedBorder: OutlineInputBorder( borderSide: BorderSide( color: Colors.indigo, width: 1.5, style: BorderStyle.solid), borderRadius: BorderRadius.all( Radius.circular( 15.0, ), ), ), prefixIcon: Icon( Icons.person, color: Colors.black, ), labelText: 'Username', // helperText: 'Your full name', labelStyle: TextStyle( color: Colors.green, fontWeight: FontWeight.normal, ), ), maxLines: 1, ), |
其中
如果是密码, 加上
1 |
obscureText:true, |
- 圆角container
1 2 3 4 5 6 7 8 9 |
Container( decoration: BoxDecoration( border: Border.all( color: Colors.red[500], ), borderRadius: BorderRadius.all(Radius.circular(20)) ), child: ... ) |
- 多个widget放到一个container里面 , 和container外面的widget 分别设置position
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Welcome to Flutter', home: Scaffold( appBar: AppBar( title: Text('Welcome to Flutter'), ), body: Stack( alignment: Alignment.center, children: <Widget>[ Positioned( left: 10, child: Container( alignment: Alignment.center, child: RaisedButton( onPressed: () {}, child: Text('Show'), ), ), ), Positioned( //right: MediaQuery.of(context).size.width * .20, right: 10, child: Container( alignment: Alignment.center, padding: EdgeInsets.all(10.0), //child: show ? CircularProgressIndicator() : Container(), child : Row( children: <Widget>[ CircularProgressIndicator(), CircularProgressIndicator(), ], ), ), ) ], ) ), ); } } |
flutter how to get current location
- at the beginning , try to use this package :
1 |
geolocator: ^5.1.3 |
the usage see : https://www.digitalocean.com/community/tutorials/flutter-geolocator-plugin
but this method not work at my huawei test device
- 改用这种方法仍然不对
1 |
https://medium.com/flutter-community/finding-users-location-in-flutter-831d40f49c08 |
- 那么是国内墙的问题, 还是手机问题,还是程序问题 ?
分析: 从
1 |
geolocator: ^3.0.0 |
以上版本, 需要项目升级为androidX , 如不想升级只能用3.0.0版本以下
,
此外, 还不知道这个package 是不是要求手机必须有google地图, 或者googl play
- 能不能不使用这个package , 直接用手机gps功能取 地理位置
flutter 怎么生成动态或者静态的listview
flutter qr code app document
- Profile 页面从这里抄 :
https://github.com/Mohammed-Benotmane/Profile-UI-Dark-And-White-Themes
效果图:
Edit profile 页面, 从这里抄:
https://github.com/alpinnz/app_flutter/blob/master/lib/feature/setting/profile/profile.dart
- login 界面从这里抄:
- 扫描 qrcode , 用这个package
1 |
barcode_scan: 2.0.2 |
从这个项目抄 : https://github.com/myvsparth/flutter_barcode_scan
- 在app内获取地理信息并生成可打印的qr code
- 生成测试用 qrcode , 去这个网站
https://www.the-qrcode-generator.com/
更好的qr code 生成网站 : http://qr.calm9.com/cn/
可以包含经纬度
- 经测试
1 |
location: ^3.0.2 |
这个package 需要 google play 服务 , 在我的华为手机测不了
- http request 测试部分
1 : 需要从服务器取得的数据包括 :
login , login 之后个人的profile , site info
全部任务列表, 以及如果是登录状态 , 我的收集
全部我的收集
既然涉及到登录, 那么如何在本地保存各种登录的token : https://www.jianshu.com/p/8d28e60af440
github 用到登录token 的例子 : https://github.com/gabryelferreira/chat_app
flutter + node.js token 教程 : https://dev.to/carminezacc/user-authentication-jwt-authorization-with-flutter-and-node-176l
node.js token jwt 的中文讲解: https://ninghao.net/blog/2834
2: 如果在本地存放键值对 , 可以用 : shared_preferences plugin.
https://flutter.dev/docs/cookbook/persistence/key-value
3 需要测试的 http 功能 : get , post
get 在这个网址有例子 : https://flutter.dev/docs/cookbook/networking/fetch-data
post 是 : https://flutter.dev/docs/cookbook/networking/send-data
server 端的post server 这样测试:
curl -d “username=scott&password=secret&website=stackabuse.com” -X POST http://localhost:8080/post-test
服务器代码: https://stackabuse.com/get-http-post-body-in-express-js/
从 http response 取字段值 https://flutter-io-deploy-one.firebaseapp.com/networking/
框架 :
https://github.com/ditclear/mvvm_flutter
网络请求用 dio package , 不自己写HTTPs
temp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
import 'package:flutter/material.dart'; import 'dart:ui' as ui; void main() => runApp(new MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Profile Demo', theme: new ThemeData( primarySwatch: Colors.blue, ), home: new MyHomePage(title: 'Profile'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => new _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { final _width = MediaQuery.of(context).size.width; final _height = MediaQuery.of(context).size.height; final String imgUrl = 'https://pixel.nymag.com/imgs/daily/selectall/2017/12/26/26-eric-schmidt.w700.h700.jpg'; return new Stack(children: <Widget>[ new Container(color: Colors.blue,), new Image.network(imgUrl, fit: BoxFit.fill,), new BackdropFilter( filter: new ui.ImageFilter.blur( sigmaX: 6.0, sigmaY: 6.0, ), child: new Container( decoration: BoxDecoration( color: Colors.blue.withOpacity(0.9), borderRadius: BorderRadius.all(Radius.circular(50.0)), ),)), new Scaffold( appBar: new AppBar( title: new Text(widget.title), centerTitle: false, elevation: 0.0, backgroundColor: Colors.transparent, ), drawer: new Drawer(child: new Container(),), backgroundColor: Colors.transparent, body: new Center( child: new Column( children: <Widget>[ new SizedBox(height: _height/12,), new CircleAvatar(radius:_width<_height? _width/4:_height/4,backgroundImage: NetworkImage(imgUrl),), new SizedBox(height: _height/25.0,), new Text('Eric Schmidt', style: new TextStyle(fontWeight: FontWeight.bold, fontSize: _width/15, color: Colors.white),), new Padding(padding: new EdgeInsets.only(top: _height/30, left: _width/8, right: _width/8), child:new Text('Snowboarder, Superhero and writer.\nSometime I work at google as Executive Chairman ', style: new TextStyle(fontWeight: FontWeight.normal, fontSize: _width/25,color: Colors.white),textAlign: TextAlign.center,) ,), new Divider(height: _height/30,color: Colors.white,), new Row( children: <Widget>[ rowCell(343, 'POSTS'), rowCell(673826, 'FOLLOWERS'), rowCell(275, 'FOLLOWING'), ],), new Divider(height: _height/30,color: Colors.white), new Padding(padding: new EdgeInsets.only(left: _width/8, right: _width/8), child: new FlatButton(onPressed: (){}, child: new Container(child: new Row(mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[ new Icon(Icons.person), new SizedBox(width: _width/30,), new Text('FOLLOW') ],)),color: Colors.blue[50],),), ], ), ) ) ],); } Widget rowCell(int count, String type) => new Expanded(child: new Column(children: <Widget>[ new Text('$count',style: new TextStyle(color: Colors.white),), new Text(type,style: new TextStyle(color: Colors.white, fontWeight: FontWeight.normal)) ],)); } |
How to write a auto gather program using python
1 安装 opencv , 在设置好的虚拟目录执行
1 |
pip install opencv-python |
再安装 pyautogui
1 |
pip install pyautogui |
2 python + opencv 截屏
1 2 3 4 5 6 7 8 9 10 11 |
import numpy as np import pyautogui import cv2 # take a screenshot of the screen and store it in memory, then # convert the PIL/Pillow image to an OpenCV compatible NumPy array # and finally write the image to disk image = pyautogui.screenshot() image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR) cv2.imwrite("in_memory_to_disk.png", image) |
3: How do I find an image contained within an image? From :
https://stackoverflow.com/questions/7853628/how-do-i-find-an-image-contained-within-an-image
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
import cv2 method = cv2.TM_SQDIFF_NORMED # Read the images from the file small_image = cv2.imread('small_image.png') large_image = cv2.imread('large_image.png') result = cv2.matchTemplate(small_image, large_image, method) # We want the minimum squared difference mn,_,mnLoc,_ = cv2.minMaxLoc(result) # Draw the rectangle: # Extract the coordinates of our best match MPx,MPy = mnLoc # Step 2: Get the size of the template. This is the same size as the match. trows,tcols = small_image.shape[:2] #print(trows) #print(tcols) # Step 3: Draw the rectangle on large_image cv2.rectangle(large_image, (MPx,MPy),(MPx+tcols,MPy+trows),(0,0,255),2) # Display the original image with the rectangle around the match. cv2.imshow('output',large_image) # The image is only displayed if we call this cv2.waitKey(0) |
这段代码会在大图上, 以矩形标出match 的部分 , if exist match
4 在 windows , python 37 ,32位环境, 执行这段代码能找出 exactly match 的部分, 并自动把鼠标移动到那里, 点击右键
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
import cv2 import pyscreenshot as ImageGrab import numpy as np import autopy import pyautogui import os import time import math dev = True def check_screen_size(): print("Checking screen size") img = ImageGrab.grab() # img.save('temp.png') global screen_size global screen_start_point global screen_end_point screen_size = (img.size[0] / 2, img.size[1] / 2) #screen_size = (img.size[0], img.size[1]) screen_start_point = (screen_size[0] * 0.35, screen_size[1] * 0.35) screen_end_point = (screen_size[0] * 0.65, screen_size[1] * 0.65) print ("Screen size is " + str(screen_size)) def make_screenshot(): print('Capturing screen') print(screen_start_point) #screenshot = ImageGrab.grab(bbox=(screen_start_point[0], screen_start_point[1], #screen_end_point[0], screen_end_point[1])) # (0, 710, 410, 1010) image = pyautogui.screenshot(region=(0,0, 1920, 1080)) if dev: screenshot_name = 'var/fishing_session_' + str(int(time.time())) + '.png' else: screenshot_name = 'var/fishing_session.png' #screenshot.save(screenshot_name) image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR) cv2.imwrite(screenshot_name, image) return screenshot_name def find_float(img_name): print('Looking for float') # todo: maybe make some universal float without background? for x in range(0, 1): #template = cv2.imread('small_image.png', 0) template = cv2.imread('yinye.png', 0) img_rgb = cv2.imread(img_name) img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY) # print('got images') w, h = template.shape[::-1] res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED) # We want the minimum squared difference mn,_,mnLoc,_ = cv2.minMaxLoc(res) # Draw the rectangle: # Extract the coordinates of our best match MPx,MPy = mnLoc print(MPx) print(MPy) threshold = 0.4 loc = np.where( res >= threshold) for pt in zip(*loc[::-1]): cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2) if loc[0].any(): print('Found ' + str(x) + ' float') if dev: cv2.imwrite('var/fishing_session_' + str(int(time.time())) + '_success.png', img_rgb) #return (loc[1][0] + w / 2) / 2, (loc[0][0] + h / 2) / 2 return pt[0] + w/2, pt[1] + h/2 def move_mouse(place): x,y = place[0], place[1] #print("Moving cursor to " + str(place)) #autopy.mouse.smooth_move(int(screen_start_point[0]) + x , int(screen_start_point[1]) + y) autopy.mouse.move(0,0) #autopy.mouse.move(x, y) autopy.mouse.smooth_move(x, y) #def main(): if __name__ == '__main__': check_screen_size() im = make_screenshot() place = find_float(im) move_mouse(place) autopy.mouse.click(autopy.mouse.Button.RIGHT) #print(place) #if not place: # print('Still cant find float, breaking this session') #print ('catched ') |
缺点是只能精确匹配, 图像稍有差别 , 或者放大缩小,变换镜头角度都不行
已经有人提出过这个问题, 在 : https://answers.opencv.org/question/169613/how-does-macthtemplate-deal-with-scaling/
关键字:
1 |
matchTemplate is not scale invariant |
意思是 opencv 的 matchTemplate 函数不是比例变换不相关的
那么, 如何使 matchTemplate 可以比较不同比例的图像, 参见这个文章:
https://www.pyimagesearch.com/2015/01/26/multi-scale-template-matching-using-python-opencv/
in this article , 解决方法是: 对于大图, 循环放大缩小多次, 以匹配小图 , 但是, 这样只是解决了比例问题, 还是没解决角度问题
更先进的方法应该是: 特征匹配或者关键点匹配, 参见文章:
或者这个文章 更好一些: https://blog.csdn.net/HuangZhang_123/article/details/80660688
找到特征匹配后, 如何找相应点的坐标: https://stackoverflow.com/questions/30716610/how-to-get-pixel-coordinates-from-feature-matching-in-opencv-python
关键字 : cv2.cornerHarris 函数
理论分析和实现 SIFT算法 : https://www.geek-share.com/detail/2777206412.html
5 如何模糊匹配, 即无论图像缩放, 观察角度的变化, 都能正确匹配到
参考文章 : https://www.lagou.com/lgeduarticle/74061.html
这个不一定对