1678715056
reactive_wechat_camera_picker
Wrapper around wechat_camera_picker to use with reactive_forms
Docs in progress. See example
folder for sample.
Run this command:
With Flutter:
$ flutter pub add reactive_wechat_camera_picker
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
reactive_wechat_camera_picker: ^0.0.1
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:reactive_wechat_camera_picker/reactive_wechat_camera_picker.dart';
import 'package:flutter/material.dart';
import 'package:reactive_wechat_camera_picker/reactive_wechat_camera_picker.dart';
import 'package:reactive_forms/reactive_forms.dart';
import 'package:reactive_wechat_camera_picker_example/selected_asset_view.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
FormGroup buildForm() => fb.group({
'input': FormControl<AssetEntity>(value: null),
});
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Scaffold(
appBar: AppBar(),
body: SafeArea(
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.symmetric(
horizontal: 20.0,
vertical: 20.0,
),
child: ReactiveFormBuilder(
form: buildForm,
builder: (context, form, child) {
return Column(
children: [
ReactiveWechatCameraPicker<AssetEntity>(
formControlName: 'input',
imagePickerBuilder: (pick, image, _) {
return Column(
children: [
if (image != null)
SelectedAssetView(
asset: image,
isDisplayingDetail: ValueNotifier(true),
onRemoveAsset: () {},
),
ElevatedButton(
onPressed: pick,
child: const Text('Pick'),
),
],
);
},
),
ElevatedButton(
child: const Text('Submit'),
onPressed: () {
if (form.valid) {
debugPrint(form.value.toString());
}
},
),
],
);
},
),
),
),
),
);
}
}
Download Details:
Author: artflutter
Source Code: https://github.com/artflutter/reactive_forms_widgets/tree/master/packages/reactive_wechat_camera_picker
1668328946
image_pickers支持本地图片多选,本地视频多选,支持将网络图片保存到相册,支持截图保存到相册,支持将网络视频保存到相册,支持预览视频和预览图片功能,支持主题颜色设置
image pickers support multi-selection of local pictures, multi-selection of local videos, support for saving network pictures to albums, support for saving screenshots to albums, support for saving network videos to albums, support for preview videos and preview images, and support for theme color settings
Supported Platforms
- Android
- iOS
# add this line to your dependencies
image_pickers: ^2.0.0+2
import 'package:image_pickers/image_pickers.dart';
///选择多张图片 Select multiple images
Future<void> selectImages() async {
List<Media> _listImagePaths = await ImagePickers.pickerPaths(
galleryMode: GalleryMode.image,
selectCount: 2,
showGif: false,
showCamera: true,
compressSize: 500,
uiConfig: UIConfig(uiThemeColor: Color(0xffff0f50)),
cropConfig: CropConfig(enableCrop: false, width: 2, height: 1));
}
/// 或者 or
ImagePickers.pickerPaths().then((List medias){
/// medias 照片路径信息 Photo path information
});
///选择多个视频 Select multiple videos
Future<void> selectVideos() async {
List<Media> _listVideoPaths = await ImagePickers.pickerPaths(
galleryMode: GalleryMode.video,
selectCount: 5,
);
}
///直接打开相机拍摄图片 Open the camera directly to take a picture
ImagePickers.openCamera().then((Media? media){
/// media 包含照片路径信息 Include photo path information
/// 未拍照返回 media = null
if(media != null){
}
});
///直接打开相机拍摄视频 Open the camera directly to shoot the video
ImagePickers.openCamera(cameraMimeType: CameraMimeType.video).then((media){
/// media 包含视频路径信息 Contains video path information
/// 未拍摄视频返回 media = null
if(media != null){
}
});
///预览图片 Preview picture
ImagePickers.previewImage(_listImagePaths[index].path);
///预览多张图片 Preview multiple pictures
ImagePickers.previewImagesByMedia(_listImagePaths,index);
///预览多张图片 Preview multiple pictures
ImagePickers.previewImages(paths,index);
///预览视频 Preview video
ImagePickers.previewVideo(_listVideoPaths[index].path);
///保存图片到图库 Save image to gallery
ImagePickers.saveImageToGallery("http://i1.sinaimg.cn/ent/d/2008-06-04/U105P28T3D2048907F326DT20080604225106.jpg");
/// 保存截图图片 ByteData 到图库 Save screenshot image ByteData to gallery
RenderRepaintBoundary boundary = globalKey.currentContext.findRenderObject();
ui.Image image = await boundary.toImage(pixelRatio: 3);
ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
Uint8List data = byteData.buffer.asUint8List();
String dataImagePath = await ImagePickers.saveByteDataImageToGallery(data,);
///保存视频到图库 Save video to gallery
ImagePickers.saveVideoToGallery("http://xxxx/xx/xx.mp4");
Add the following entry to your Info.plist
file, located in /Info.plist
: <key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict> <key>NSMicrophoneUsageDescription</key> <string>...</string> <key>NSPhotoLibraryAddUsageDescription</key> <string>...</string> <key>NSCameraUsageDescription</key> <string>...</string> <key>NSPhotoLibraryUsageDescription</key> <string>...</string>
Run this command:
With Flutter:
$ flutter pub add image_pickers
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
image_pickers: ^2.0.0+2
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:image_pickers/image_pickers.dart';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:image_pickers/image_pickers.dart';
import 'dart:ui' as ui;
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
GalleryMode _galleryMode = GalleryMode.image;
GlobalKey? globalKey;
@override
void initState() {
super.initState();
globalKey = GlobalKey();
}
List<Media> _listImagePaths = [];
List<Media> _listVideoPaths = [];
String? dataImagePath = "";
Future<void> selectImages() async {
try {
_galleryMode = GalleryMode.image;
_listImagePaths = await ImagePickers.pickerPaths(
galleryMode: _galleryMode,
showGif: true,
selectCount: 2,
showCamera: true,
cropConfig :CropConfig(enableCrop: true,height: 1,width: 1),
compressSize: 500,
uiConfig: UIConfig(uiThemeColor: Color(0xffff0000),
),
);
print(_listImagePaths.length);
if(_listImagePaths.length > 0){
_listImagePaths.forEach((media){
print(media.path.toString());
});
}
setState(() {
});
} on PlatformException {}
}
Future<void> selectVideos() async {
try {
_galleryMode = GalleryMode.video;
_listVideoPaths = await ImagePickers.pickerPaths(
galleryMode: _galleryMode,
selectCount: 2,
showCamera: true,
);
setState(() {
});
print(_listVideoPaths);
} on PlatformException {}
}
@override
Widget build(BuildContext context) {
return RepaintBoundary(
key: globalKey,
child: MaterialApp(
theme: ThemeData(
backgroundColor: Colors.white,
primaryColor: Colors.white,
),
home: Scaffold(
appBar: AppBar(
title: const Text('多图选择'),
),
body: SingleChildScrollView(
physics: BouncingScrollPhysics(),
child: Column(
children: <Widget>[
GridView.builder(
physics: NeverScrollableScrollPhysics(),
itemCount: _listImagePaths.length,
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 20.0,
crossAxisSpacing: 10.0,
childAspectRatio: 1.0),
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onTap: (){
// ImagePickers.previewImage(_listImagePaths[index].path);
// List<String> paths = [];
// _listImagePaths.forEach((media){
// paths.add(media.path);
// });
//
// ImagePickers.previewImages(paths,index);
ImagePickers.previewImagesByMedia(_listImagePaths,index);
},
child: Image.file(
File(
_listImagePaths[index].path!,
),
fit: BoxFit.cover,
),
);
}),
ElevatedButton(
onPressed: () {
selectImages();
},
child: Text("选择图片"),
),
ElevatedButton(
onPressed: () async {
ImagePickers.openCamera(cropConfig: CropConfig(enableCrop: false, width: 2, height: 3)).then((Media? media){
_listImagePaths.clear();
if(media != null){
_listImagePaths.add(media);
}
setState(() {
});
});
},
child: Text("拍照"),
),
ElevatedButton(
onPressed: () {
ImagePickers.openCamera(cameraMimeType: CameraMimeType.video).then((media){
_listVideoPaths.clear();
if(media != null){
print(media.path);
_listVideoPaths.add(media);
}
setState(() {
});
});
},
child: Text("拍视频"),
),
GridView.builder(
physics: NeverScrollableScrollPhysics(),
itemCount: _listVideoPaths.length,
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 20.0,
crossAxisSpacing: 10.0,
childAspectRatio: 1.0),
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onTap: (){
ImagePickers.previewVideo(_listVideoPaths[index].path!,);
},
child: Image.file(
File(
_listVideoPaths[index].thumbPath!,
),
fit: BoxFit.cover,
),
);
}),
ElevatedButton(
onPressed: () {
selectVideos();
},
child: Text("选择视频"),
),
InkWell(
onTap: (){
ImagePickers.previewImage("http://i1.sinaimg.cn/ent/d/2008-06-04/U105P28T3D2048907F326DT20080604225106.jpg");
},
child: Image.network("http://i1.sinaimg.cn/ent/d/2008-06-04/U105P28T3D2048907F326DT20080604225106.jpg",fit: BoxFit.cover,width: 100,height: 100,)),
ElevatedButton(
onPressed: () {
Future<String?> future = ImagePickers.saveImageToGallery("http://i1.sinaimg.cn/ent/d/2008-06-04/U105P28T3D2048907F326DT20080604225106.jpg");
future.then((path){
print("保存图片路径:"+ path!);
});
},
child: Text("保存网络图片"),
),
dataImagePath == "" ? Container():GestureDetector(onTap: (){
ImagePickers.previewImage(dataImagePath!);
},child: Image.file(File(dataImagePath!),fit: BoxFit.cover,width: 100,height: 100,)),
ElevatedButton(
onPressed: () async {
RenderRepaintBoundary boundary = globalKey!.currentContext!.findRenderObject() as RenderRepaintBoundary;
ui.Image image = await boundary.toImage(pixelRatio: 3);
ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png) as ByteData;
Uint8List data = byteData.buffer.asUint8List();
dataImagePath = await ImagePickers.saveByteDataImageToGallery(data,);
print("保存截屏图片 = "+ dataImagePath!);
setState(() {
});
},
child: Text("保存截屏图片"),
),
ElevatedButton(
onPressed: () {
Future<String?> future = ImagePickers.saveVideoToGallery("http://vd4.bdstatic.com/mda-jbmn50510sid5yx5/sc/mda-jbmn50510sid5yx5.mp4");
future.then((path){
print("视频保存成功"+path!);
});
},
child: Text("保存视频"),
),
],
),
),
),
),
);
}
}
Download Details:
Author:
Source Code: https://pub.dev/packages/image_pickers
1667799426
A multiple image picker for iOS.
Info.plist
To be able to request permission to the users photo library you need to add this to your Info.plist
<key>NSPhotoLibraryUsageDescription</key>
<string>Why you want to access photo library</string>
Image picker
import BSImagePicker
let imagePicker = ImagePickerController()
presentImagePicker(imagePicker, select: { (asset) in
// User selected an asset. Do something with it. Perhaps begin processing/upload?
}, deselect: { (asset) in
// User deselected an asset. Cancel whatever you did when asset was selected.
}, cancel: { (assets) in
// User canceled selection.
}, finish: { (assets) in
// User finished selection assets.
})
PHAsset
So you have a bunch of PHAssets now, great. But how do you use them? To get an UIImage from the asset you use a PHImageManager.
import Photos
// Request the maximum size. If you only need a smaller size make sure to request that instead.
PHImageManager.default().requestImage(for: asset, targetSize: PHImageManagerMaximumSize, contentMode: .aspectFit, options: nil) { (image, info) in
// Do something with image
}
For more example you can clone this repo and look at the example app.
Add the following line to your Podfile:
pod "BSImagePicker", "~> 3.1"
Add the following line to your Cartfile:
github "mikaoj/BSImagePicker" ~> 3.1
Add it to the dependencies value of your Package.swift.:
dependencies: [
.package(url: "https://github.com/mikaoj/BSImagePicker.git", from: "version-tag")
]
If you are Xamarin developer you can use Net.Xamarin.iOS.BSImagePicker
Users are encouraged to become active participants in its continued development — by fixing any bugs that they encounter, or by improving the documentation wherever it’s found to be lacking.
If you wish to make a change, open a Pull Request — even if it just contains a draft of the changes you’re planning, or a test that reproduces an issue — and we can discuss it further from there.
Author: Mikaoj
Source Code: https://github.com/mikaoj/BSImagePicker
License: MIT license
1667145718
flutter_timpage_picker
A new flutter plugin project.
This project is a starting point for a Flutter plug-in package, a specialized package that includes platform-specific implementation code for Android and/or iOS.
For help getting started with Flutter, view our online documentation, which offers tutorials, samples, guidance on mobile development, and a full API reference.
Run this command:
With Flutter:
$ flutter pub add flutter_timpage_picker
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
flutter_timpage_picker: ^1.0.0
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:flutter_timpage_picker/flutter_timpage_picker.dart';
example/lib/main.dart
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:flutter_timpage_picker/flutter_timpage_picker.dart';
import 'package:flutter_timpage_picker/image_picker_option.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown';
@override
void initState() {
super.initState();
initPlatformState();
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
String platformVersion;
// Platform messages may fail, so we use a try/catch PlatformException.
// We also handle the message potentially returning null.
try {
platformVersion = await FlutterTimpagePicker.platformVersion ??
'Unknown platform version';
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Column(
children: [
Text('Running on: $_platformVersion\n'),
ElevatedButton(
onPressed: () async {
PickOptions options = PickOptions();
options.imageCount = 1;
options.isCrop = false;
options.isCamera = false;
options.showSelectedIndex = false;
options.isRecordSelected = true;
var ret = await FlutterTimpagePicker.showImagePicker(options);
print("result:" + ret.toString());
},
child: Text("选择照片"),
),
ElevatedButton(
onPressed: () async {
PickOptions options = PickOptions();
options.imageCount = 1;
options.isCrop = true;
options.isCamera = false;
options.showSelectedIndex = false;
options.isRecordSelected = true;
var ret = await FlutterTimpagePicker.openCamera(options);
if (ret == null) {
print("camera null");
} else {
print("camera result:" + ret.toString());
}
},
child: Text("拍照"),
),
],
)),
),
);
}
}
Download Details:
Author:
Source Code: https://pub.dev/packages/flutter_timpage_picker
1665911250
Advanced Image Picker
This is my custom Image Picker that enabling you to multiple pick image and Adv Camera with our Custom UI
Note: This plugin is still under development, and some Components might not be available yet or still has so many bugs.
First, add adv_image_picker
as a dependency in your pubspec.yaml file.
If you are about to load the image in thumbnail size, it is recommended to get the image bytes from AdvImagePickerPlugin.getThumbnail Otherwise, it will be causing memory issue
adv_image_picker: ^1.0.6
You can find the full example, here
Run this command:
With Flutter:
$ flutter pub add adv_image_picker
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
adv_image_picker: ^2.0.2
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:adv_image_picker/adv_image_picker.dart';
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:adv_image_picker/adv_image_picker.dart';
import 'package:adv_image_picker/plugins/adv_image_picker_plugin.dart';
import 'package:flutter/material.dart';
void main() {
CustomImageCache();
runApp(MyApp());
}
class CustomImageCache extends WidgetsFlutterBinding {
@override
ImageCache createImageCache() {
ImageCache imageCache = super.createImageCache();
// Set your image cache size
imageCache.maximumSize = 10;
return imageCache;
}
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Image Picker Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<File> files = [];
List<ImageProvider> thumbnails = [];
bool isPreparing = false;
@override
void initState() {
super.initState();
AdvImagePicker.cameraFolderName = "Camera Folder";
AdvImagePicker.cameraFilePrefixName = "CameraTestingPrefixName_";
AdvImagePicker.cameraSavePath = "/storage/emulated/0/CameraTestingFolder/";
}
@override
void dispose() {
//flushing every memory that was taken before
if ((thumbnails?.length ?? 0) > 0) {
for (ImageProvider each in thumbnails) {
each.evict();
}
}
super.dispose();
}
void _pickImage() async {
files.addAll(await AdvImagePicker.pickImagesToFile(context, maxSize: 4080));
print("files => ${files.map((e) => e.path).join("\n")}");
prepare();
}
Future<void> prepare() async {
List<ImageProvider> thumbnails = [];
double screenWidth = MediaQuery.of(context).size.width;
for (int i = 0; i < files.length; i++) {
String path = files[i].path;
ByteData data = await AdvImagePickerPlugin.getAlbumThumbnail(
imagePath: path,
height: screenWidth ~/ 4,
width: screenWidth ~/ 4,
);
Uint8List imageData = data.buffer.asUint8List();
thumbnails.add(MemoryImage(imageData));
}
this.thumbnails = List<ImageProvider>.from(thumbnails);
if (this.mounted) setState(() {});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: isPreparing ? CircularProgressIndicator() : GridView.count(
crossAxisCount: 4,
children: thumbnails
.map((ImageProvider image) => Image(
image: image,
fit: BoxFit.cover,
))
.toList(),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _pickImage,
child: Icon(Icons.add),
),
);
}
}
Download Details:
Author: ricnaaru
Source Code: https://github.com/ricnaaru/adv_image_picker
1665417095
Animated Item Picker
Generic item picker that encapsulates single or multiple item selection logic.
Suitable for fixed size item lists, e.g level, week day or gender selector etc.
Supports tapUp/tapDown item opacity animation.
@override
Widget build(BuildContext context) {
return AnimatedItemPicker(
axis: Axis.horizontal,
multipleSelection: false,
itemCount: yourModelList.length,
pressedOpacity: 0.85,
initialSelection: {defaultItemIndex},
onItemPicked: (index, selected) {
},
itemBuilder: (index, animValue, selected) => _YourItemWidget(
name: yourModelList[index].name,
borderColor: _colorTween1.transform(animValue),
textColor: _colorTween2.transform(animValue),
iconColor: _colorTween3.transform(animValue)
),
);
}
Run this command:
With Flutter:
$ flutter pub add animated_item_picker
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
animated_item_picker: ^1.0.5+1
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:animated_item_picker/animated_item_picker.dart';
import 'package:animated_item_picker/animated_item_picker.dart';
import 'package:example/model/day_of_week.dart';
import 'package:example/model/level.dart';
import 'package:example/ui/helper.dart';
import 'package:example/ui/item_widgets.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: Material(child: HomePage(), color: Colors.black));
}
}
class HomePage extends StatelessWidget {
static ColorTween _firstPickerColorTween1 = ColorTween(begin: Colors.white, end: Colors.redAccent);
static ColorTween _firstPickerColorTween2 = ColorTween(begin: Colors.black, end: Colors.redAccent);
static ColorTween _secondPickerColorTween1 = ColorTween(begin: Colors.black, end: Colors.yellow);
static ColorTween _secondPickerColorTween2 = ColorTween(begin: Colors.white, end: Colors.yellow);
@override
Widget build(BuildContext context) {
return Column(mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [
decorateFirstItemPicker(
AnimatedItemPicker(
axis: Axis.horizontal,
multipleSelection: false,
itemCount: Level.LIST.length,
pressedOpacity: 0.85,
initialSelection: {Level.LIST.indexOf(Level.BEGINNER)},
expandedItems: true,
onItemPicked: (index, selected) {
print("Gender: ${Level.LIST[index]}, selected: $selected");
},
itemBuilder: (index, animValue) => GenderItemWidget(
name: Level.LIST[index].toString(),
borderColor: _firstPickerColorTween2.transform(animValue)!,
textColor: _firstPickerColorTween1.transform(animValue)!,
)),
),
decorateSecondItemPicker(
AnimatedItemPicker(
axis: Axis.vertical,
multipleSelection: true,
itemCount: DayOfWeek.LIST.length,
maxItemSelectionCount: 6,
expandedItems: true,
initialSelection: {1},
onItemPicked: (index, selected) {
print("Day: ${DayOfWeek.LIST[index]}, selected: $selected");
},
itemBuilder: (index, animValue) => DayItemWidget(
name: DayOfWeek.LIST[index],
textColor: _secondPickerColorTween2.transform(animValue)!,
backgroundColor: _secondPickerColorTween1.transform(animValue)!,
),
),
),
]);
}
}
Download Details:
Author: kirn-tech/
Source Code: https://github.com/kirn-tech/animated_item_picker
1665213177
Shows a full screen modal dialog containing a Material Design date range picker.
void showCustomRangePicker() async {
var res = await showTCRDateRangePicker(
context: context,
// selectRange: CustomDateTimeRange(start: DateTime.now(), end: DateTime.now().add(Duration(days: 6))),
selectRange: CustomDateTimeRange(),
validRange: CustomDateTimeRange(start: DateTime(2021, 1), end: DateTime(2022, 7)),
);
print('res = $res');
}
Run this command:
With Flutter:
$ flutter pub add z_date_range_picker
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
z_date_range_picker: ^0.0.5
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:z_date_range_picker/date_range_picker.dart';
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:z_date_range_picker/date_range_picker.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
restorationScopeId: 'app',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page', restorationId: 'main'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, this.title, this.restorationId}) : super(key: key);
final String? title;
final String? restorationId;
@override
_MyHomePageState createState() => _MyHomePageState();
}
/// https://api.flutter.dev/flutter/material/showDateRangePicker.html
class _MyHomePageState extends State<MyHomePage> {
// with RestorationMixin
@override
String? get restorationId => widget.restorationId;
// final RestorableDateTimeN _startDate = RestorableDateTimeN(DateTime(2021, 1, 1));
// final RestorableDateTimeN _endDate = RestorableDateTimeN(DateTime(2021, 1, 5));
// late final RestorableRouteFuture<DateTimeRange?> _restorableDateRangePickerRouteFuture = RestorableRouteFuture<DateTimeRange?>(
// onComplete: _selectDateRange,
// onPresent: (NavigatorState navigator, Object? arguments) {
// return navigator.restorablePush(_dateRangePickerRoute, arguments: <String, dynamic>{
// 'initialStartDate': _startDate.value?.millisecondsSinceEpoch,
// 'initialEndDate': _endDate.value?.millisecondsSinceEpoch,
// });
// },
// );
//
// void _selectDateRange(DateTimeRange? newSelectedDate) {
// if (newSelectedDate != null) {
// setState(() {
// _startDate.value = newSelectedDate.start;
// _endDate.value = newSelectedDate.end;
// });
// }
// }
//
// @override
// void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
// registerForRestoration(_startDate, 'start_date');
// registerForRestoration(_endDate, 'end_date');
// registerForRestoration(_restorableDateRangePickerRouteFuture, 'date_picker_route_future');
// }
//
// static Route<DateTimeRange?> _dateRangePickerRoute(
// BuildContext context,
// Object? arguments,
// ) {
// return DialogRoute<DateTimeRange?>(
// context: context,
// builder: (BuildContext context) {
// return DateRangePickerDialog(
// restorationId: 'date_picker_dialog',
// initialDateRange: _initialDateTimeRange(arguments! as Map<dynamic, dynamic>),
// firstDate: DateTime(2021, 1, 1),
// currentDate: DateTime(2021, 1, 25),
// lastDate: DateTime(2022, 1, 1),
// );
// },
// );
// }
//
// static DateTimeRange? _initialDateTimeRange(Map<dynamic, dynamic> arguments) {
// if (arguments['initialStartDate'] != null && arguments['initialEndDate'] != null) {
// return DateTimeRange(
// start: DateTime.fromMillisecondsSinceEpoch(arguments['initialStartDate'] as int),
// end: DateTime.fromMillisecondsSinceEpoch(arguments['initialEndDate'] as int),
// );
// }
//
// return null;
// }
void showCustomRangePicker() async {
var res = await showTCRDateRangePicker(
context: context,
// selectRange: CustomDateTimeRange(start: DateTime.now(), end: DateTime.now().add(Duration(days: 6))),
selectRange: CustomDateTimeRange(),
validRange: CustomDateTimeRange(start: DateTime(2021, 1), end: DateTime(2022, 7)),
);
print('res = $res');
}
void showSystemRangePicker() async {}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title ?? 'X'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextButton(onPressed: showCustomRangePicker, child: Text('show date range picker')),
TextButton(onPressed: showCustomRangePicker, child: Text('show system date range picker')),
],
),
),
);
}
}
Download Details:
Author: qqzhao
Source Code: https://gitee.com/qqzhao/flutter_pubs
1663252366
progressive_time_picker
A Customizable Progressive Time Picker for Flutter. This package allow us to customize time picker based on our requirements for selecting a specific range from time picker and it's supports multiple platforms.
Preview
Import it to your project file
import 'package:progressive_time_picker/progressive_time_picker.dart';
And add it in its most basic form like it:
TimePicker(
initTime: PickedTime(h: 0, m: 0),
endTime: PickedTime(h: 8, m: 0),
onSelectionChange: (a, b) =>
print(
'onSelectionChange => init : ${a.h}:${a.m}, end : ${b.h}:${b.m}'),
onSelectionEnd: (a, b) =>
print(
'onSelectionEnd => init : ${a.h}:${a.m}, end : ${b.h}:${b.m}'),
);
Parameter | Description |
---|---|
PickedTime initTime | the init PickedTime value in the selection |
PickedTime endTime | the end PickedTime value in the selection |
onSelectionChange | callback function when init and end PickedTime change |
onSelectionEnd | callback function when init and end PickedTime finish |
Parameter | Default | Description |
---|---|---|
double height | 220 | height of the canvas |
double width | 220 | width of the canvas |
int primarySectors | 0 | the number of primary sectors to be painted |
int secondarySectors | 0 | the number of secondary sectors to be painted |
Widget child | Container | widget that would be mounted inside the circle |
TimePickerDecoration decoration | - | used to decorate our TimePicker widget |
bool isInitHandlerSelectable | true | used to enabled or disabled Selection of Init Handler |
bool isEndHandlerSelectable | true | used to enabled or disabled Selection of End Handler |
Parameter | Description |
---|---|
TimePickerSweepDecoration sweepDecoration | used to decorate our sweep part or a part between our init and end point with various options |
TimePickerHandlerDecoration initHandlerDecoration | used to decorate our init or end handler of time picker |
TimePickerHandlerDecoration endHandlerDecoration | used to decorate our init or end handler of time picker |
Parameter | Default | Description |
---|---|---|
Color baseColor | cyanAccent | defines the background color of the picker |
double pickerBaseCirclePadding | 0.0 | to add extra padding for picker base or outer circle |
TimePickerSectorDecoration primarySectorsDecoration | - | used to decorate the primary sectors of out time picker |
TimePickerSectorDecoration secondarySectorsDecoration | - | used to decorate the secondary of out time picker |
TimePickerClockNumberDecoration clockNumberDecoration | - | Provides decoration options which will get applied to the internal clock's numbers when enable |
It would be great for us if the reporter can share the below things to understand the root cause of the issue.
progressive_time_picker is MIT-licensed.
We’d be really happy if you send us links to your projects where you use our component. Just send an email to sales@mindinventory.com And do let us know if you have any questions or suggestion regarding our work
Run this command:
With Flutter:
$ flutter pub add progressive_time_picker
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
progressive_time_picker: ^0.0.6
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:progressive_time_picker/progressive_time_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:progressive_time_picker/progressive_time_picker.dart';
import 'package:intl/intl.dart' as intl;
void main() {
/// To set fixed device orientation
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]).then(
(value) => runApp(MyApp()),
);
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
debugShowCheckedModeBanner: false,
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
ClockTimeFormat _clockTimeFormat = ClockTimeFormat.TWENTYFOURHOURS;
ClockIncrementTimeFormat _clockIncrementTimeFormat =
ClockIncrementTimeFormat.FIVEMIN;
PickedTime _inBedTime = PickedTime(h: 0, m: 0);
PickedTime _outBedTime = PickedTime(h: 8, m: 0);
PickedTime _intervalBedTime = PickedTime(h: 0, m: 0);
double _sleepGoal = 8.0;
bool _isSleepGoal = false;
@override
void initState() {
super.initState();
_isSleepGoal = (_sleepGoal >= 8.0) ? true : false;
_intervalBedTime = formatIntervalTime(
init: _inBedTime,
end: _outBedTime,
clockTimeFormat: _clockTimeFormat,
clockIncrementTimeFormat: _clockIncrementTimeFormat,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFF141925),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
'Sleep Time',
style: TextStyle(
color: Color(0xFF3CDAF7),
fontSize: 30,
fontWeight: FontWeight.bold,
),
),
TimePicker(
initTime: _inBedTime,
endTime: _outBedTime,
height: 260.0,
width: 260.0,
onSelectionChange: _updateLabels,
onSelectionEnd: (a, b) => print(
'onSelectionEnd => init : ${a.h}:${a.m}, end : ${b.h}:${b.m}'),
primarySectors: _clockTimeFormat.value,
secondarySectors: _clockTimeFormat.value * 2,
decoration: TimePickerDecoration(
baseColor: Color(0xFF1F2633),
pickerBaseCirclePadding: 15.0,
sweepDecoration: TimePickerSweepDecoration(
pickerStrokeWidth: 30.0,
pickerColor: _isSleepGoal ? Color(0xFF3CDAF7) : Colors.white,
showConnector: true,
),
initHandlerDecoration: TimePickerHandlerDecoration(
color: Color(0xFF141925),
shape: BoxShape.circle,
radius: 12.0,
icon: Icon(
Icons.power_settings_new_outlined,
size: 20.0,
color: Color(0xFF3CDAF7),
),
),
endHandlerDecoration: TimePickerHandlerDecoration(
color: Color(0xFF141925),
shape: BoxShape.circle,
radius: 12.0,
icon: Icon(
Icons.notifications_active_outlined,
size: 20.0,
color: Color(0xFF3CDAF7),
),
),
primarySectorsDecoration: TimePickerSectorDecoration(
color: Colors.white,
width: 1.0,
size: 4.0,
radiusPadding: 25.0,
),
secondarySectorsDecoration: TimePickerSectorDecoration(
color: Color(0xFF3CDAF7),
width: 1.0,
size: 2.0,
radiusPadding: 25.0,
),
clockNumberDecoration: TimePickerClockNumberDecoration(
defaultTextColor: Colors.white,
defaultFontSize: 12.0,
scaleFactor: 2.0,
showNumberIndicators: true,
clockTimeFormat: _clockTimeFormat,
clockIncrementTimeFormat: _clockIncrementTimeFormat,
),
),
child: Padding(
padding: const EdgeInsets.all(62.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'${intl.NumberFormat('00').format(_intervalBedTime.h)}Hr ${intl.NumberFormat('00').format(_intervalBedTime.m)}Min',
style: TextStyle(
fontSize: 14.0,
color: _isSleepGoal ? Color(0xFF3CDAF7) : Colors.white,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
Container(
width: 300.0,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Color(0xFF1F2633),
borderRadius: BorderRadius.circular(25.0),
),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
_isSleepGoal
? "Above Sleep Goal (>=8) 😄"
: 'below Sleep Goal (<=8) 😴',
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_timeWidget(
'BedTime',
_inBedTime,
Icon(
Icons.power_settings_new_outlined,
size: 25.0,
color: Color(0xFF3CDAF7),
),
),
_timeWidget(
'WakeUp',
_outBedTime,
Icon(
Icons.notifications_active_outlined,
size: 25.0,
color: Color(0xFF3CDAF7),
),
),
],
),
],
),
);
}
Widget _timeWidget(String title, PickedTime time, Icon icon) {
return Container(
width: 150.0,
decoration: BoxDecoration(
color: Color(0xFF1F2633),
borderRadius: BorderRadius.circular(25.0),
),
child: Padding(
padding: const EdgeInsets.all(25.0),
child: Column(
children: [
Text(
'${intl.NumberFormat('00').format(time.h)}:${intl.NumberFormat('00').format(time.m)}',
style: TextStyle(
color: Color(0xFF3CDAF7),
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 15),
Text(
'$title',
style: TextStyle(
color: Color(0xFF3CDAF7),
fontSize: 16,
),
),
SizedBox(height: 10),
icon,
],
),
),
);
}
void _updateLabels(PickedTime init, PickedTime end) {
_inBedTime = init;
_outBedTime = end;
_intervalBedTime = formatIntervalTime(
init: _inBedTime,
end: _outBedTime,
clockTimeFormat: _clockTimeFormat,
clockIncrementTimeFormat: _clockIncrementTimeFormat,
);
_isSleepGoal = validateSleepGoal(
inTime: init,
outTime: end,
sleepGoal: _sleepGoal,
clockTimeFormat: _clockTimeFormat,
clockIncrementTimeFormat: _clockIncrementTimeFormat,
);
setState(() {});
}
}
Download Details:
Author: Mindinventory
Source Code: https://github.com/Mindinventory/progressive_time_picker
1662552329
In today's post we will learn about 4 Best React Image Picker Libraries.
A highly customizable, stable, responsive photo gallery React. In this components you will learn about how react works to make images different in looks. You will put carousel plugin effects, react slider, React native slider ,React image gallery intense and so on. The original ratio of your pictures is maintained and actual elements are used. It is also feasible to add additional features such as captions and favourites to your custom picture parts.
To build some examples locally, git clone and run:
yarn install
yarn start
Then open localhost:8000
in a browser.
const photos = [
{
src: 'http://example.com/example/img1.jpg',
width: 4,
height: 3
},
{
src: 'http://example.com/example/img2.jpg',
width: 1,
height: 1
}
];
<Gallery photos={photos} />;
Justified image gallery component for React inspired by Google Photos and based upon React Images.
Using npm:
npm install --save react-grid-gallery
import React from 'react';
import { render } from 'react-dom';
import Gallery from 'react-grid-gallery';
const IMAGES =
[{
src: "https://c2.staticflickr.com/9/8817/28973449265_07e3aa5d2e_b.jpg",
thumbnail: "https://c2.staticflickr.com/9/8817/28973449265_07e3aa5d2e_n.jpg",
thumbnailWidth: 320,
thumbnailHeight: 174,
isSelected: true,
caption: "After Rain (Jeshu John - designerspics.com)"
},
{
src: "https://c2.staticflickr.com/9/8356/28897120681_3b2c0f43e0_b.jpg",
thumbnail: "https://c2.staticflickr.com/9/8356/28897120681_3b2c0f43e0_n.jpg",
thumbnailWidth: 320,
thumbnailHeight: 212,
tags: [{value: "Ocean", title: "Ocean"}, {value: "People", title: "People"}],
caption: "Boats (Jeshu John - designerspics.com)"
},
{
src: "https://c4.staticflickr.com/9/8887/28897124891_98c4fdd82b_b.jpg",
thumbnail: "https://c4.staticflickr.com/9/8887/28897124891_98c4fdd82b_n.jpg",
thumbnailWidth: 320,
thumbnailHeight: 212
}]
render(
<Gallery images={IMAGES}/>,
document.getElementById('example-0')
);
react image picker
npm install --save image-upload-react
import React, { useState } from 'react'
import ImageUpload from 'image-upload-react'
//important for getting nice style.
import 'image-upload-react/dist/index.css'
function App() {
const [imageSrc, setImageSrc] = useState()
const handleImageSelect = (e) => {
setImageSrc(URL.createObjectURL(e.target.files[0]))
}
return (
<ImageUpload
handleImageSelect={handleImageSelect}
imageSrc={imageSrc}
setImageSrc={setImageSrc}
style={{
width: 700,
height: 500,
background: 'gold'
}}
/>
)
}
export default App
Render images based on optimal layout, like facebook render images inside timeline.
Install:
npm install react-smart-gallery
Use:
import SmartGallery from 'react-smart-gallery';
const images = [
'https://source.unsplash.com/random/400x400',
'https://source.unsplash.com/random/400x400',
'https://source.unsplash.com/random/400x400',
];
<SmartGallery images={images} />
Thank you for following this article.
Related videos:
1660738107
Flutter Gallery Picker
This a Flutter Gallery which allows you to pick image or video from gallery.
Here are some features:
Add this to your package's pubspec.yaml
file:
dependencies:
flutter_gallery_picker: ^0.0.4
import 'package:flutter_gallery_picker/flutter_gallery_picker.dart';
Add the following permissions to your AndroidManifest.xml, located in <project root>/android/app/src/main/AndroidManifest.xml
:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
...
<manifest/>
API 29+
Add the following property to your AndroidManifest.xml, located in <project root>/android/app/src/main/AndroidManifest.xml
to opt-out of scoped storage:
<manifest ...>
...
<application
android:requestLegacyExternalStorage="true"
...>
<application/>
<manifest/>
File image = await GalleryScreen.getImage(context);
print(image);
you can use the image as File
getImage() async {
File image = await GalleryScreen.getImage(context);
// print image path
print(image.path);
// from package rflutter_alert
Alert(
context: context,
// show image from file (image)
content: Image.file(image),
).show();
}
you can get List<File>
List<File> images = await GalleryScreen.getImage(context , multi:true);
print(images);
getImage() async {
List<File> images = await GalleryScreen.getImage(context , multi:true);
// print images list
print(images);
// from package rflutter_alert
Alert(
context: context,
// show image from file (image)
content: Image.file(image.first),
).show();
}
it's really easy :)
Thank You
, Donate to the developer.Run this command:
With Flutter:
$ flutter pub add flutter_gallery_picker
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
flutter_gallery_picker: ^0.0.4
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:flutter_gallery_picker/flutter_gallery_picker.dart';
Download Details:
Author:
Source Code: https://pub.dev/packages/flutter_gallery_picker/
1660385451
Easy Folder Picker
Easy directory picker for Flutter
A flutter package to pick directories and handles requesting required permissions as well. This package only supports ANDROID.
Add below line to your pubspec.yaml
and run flutter packages get
easy_folder_picker: ^latest version
Add below line to your android/app/src/main/AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
If you want to allow creating new folders directly from picker then add the below permission also
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
In Android 10, you need to add the Following Lines in AndroidManifest file:
<application
android:requestLegacyExternalStorage="true"
From Android 11, you need to manage permission within your app, if you want to write in different folders of external storage.
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
var status = await Permission.manageExternalStorage.status;
if (status!.isRestricted) {
status = await Permission.manageExternalStorage.request();
}
if (status!.isDenied) {
status = await Permission.manageExternalStorage.request();
}
if (status!.isPermanentlyDenied) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
backgroundColor: Colors.green,
content: Text('Please add permission for app to manage external storage'),
));
}
Flutter Usage
import 'package:easy_folder_picker/FolderPicker.dart';
// In any callback call the below method
Future<void> _pickDirectory(BuildContext context) async {
Directory directory = selectedDirectory;
if (directory == null) {
directory = Directory(FolderPicker.ROOTPATH);
}
Directory newDirectory = await FolderPicker.pick(
allowFolderCreation: true,
context: context,
rootDirectory: directory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10))));
setState(() {
selectedDirectory = newDirectory;
print(selectedDirectory);
});
}
Run this command:
With Flutter:
$ flutter pub add easy_folder_picker
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
easy_folder_picker: ^1.3.0
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:easy_folder_picker/DirectoryList.dart';
import 'package:easy_folder_picker/FolderPicker.dart';
import 'dart:io';
import 'package:easy_folder_picker/FolderPicker.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Easy Folder Picker',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Directory? selectedDirectory;
Future<void> _pickDirectory(BuildContext context) async {
Directory? directory = selectedDirectory;
if (directory == null) {
directory = Directory(FolderPicker.rootPath);
}
Directory? newDirectory = await FolderPicker.pick(
allowFolderCreation: true,
context: context,
rootDirectory: directory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10))));
setState(() {
selectedDirectory = newDirectory;
print(selectedDirectory);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Folder"),
centerTitle: true,
),
body: Container(
child: Column(
children: [
IconButton(
icon: Icon(Icons.file_download),
onPressed: () {
_pickDirectory(context);
},
),
selectedDirectory != null
? Text("Selected Path : ${selectedDirectory!.path}")
: Container(),
],
),
),
);
}
}
Download Details:
Author: kapilmhr
Source Code: https://github.com/kapilmhr/Easy-Folder-Picker
1659719030
contactor_picker
联系人选择器
dependencies:
contactor_picker: ^0.0.6
$ flutter packages get
///列表加搜索
ContactorPicker.showPicker(
context,
///数据源
dataList: [],
///是否展示code 默认不展示
showGroupCode: true,
///选中数据
onSelectedData: (data) {
},
///标题
title: '联系人',
///页面背景色
backgroundColor: Color(0xFFFAFAFA),
///当前字母颜色
letterSelectedColor: Colors.blueAccent,
);
///仅搜索
ContactorPicker.showSearchPicker(
context,
///是否展示code 默认不展示
showGroupCode: true,
///不展示
dataList: [],
///背景色
backgroundColor: Color(0xFFFAFAFA),
///选中数据
onSelectedData: (data) {
},
);
///支持嵌入其他Widget 详见example
return Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: ContactorView(
///数据源
dataList: DataUtil.dataList.map((element) {
String pinyin = PinyinHelper.getPinyinE(element['name'],
separator: " ",
defPinyin: '#',
format: PinyinFormat.WITHOUT_TONE);
return ContactorDataListData(
name: element['name'],
id: int.tryParse(element['zip']),
pinyin: pinyin,
headerImageUrl: 'https://picsum.photos/250?image=9',
code: element['label'],
groupCode: element['zip'],
);
}).toList(),
///选中item时仅选中 不附带pop动作
canPop: false,
///选中回调
onSelectedData: (ContactorDataListData data) {
print('${data.toString()}');
},
),
);
Run this command:
With Flutter:
$ flutter pub add contactor_picker
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
contactor_picker: ^0.0.7
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:contactor_picker/contactor_picker.dart';
import 'package:contactor_picker_example/data_util.dart';
import 'package:flutter/material.dart';
import 'package:contactor_picker/contactor_picker.dart';
import 'package:lpinyin/lpinyin.dart';
void main() {
runApp(MaterialApp(home: MyApp()));
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
print('length----${DataUtil.dataList.length}');
}
String _currentData = '';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
// body: ContactorView(
// dataList: DataUtil.dataList.map((element) {
// String pinyin = PinyinHelper.getPinyinE(element['name'],
// separator: " ",
// defPinyin: '#',
// format: PinyinFormat.WITHOUT_TONE);
// return ContactorDataListData(
// name: element['name'],
// id: int.tryParse(element['zip']),
// pinyin: pinyin,
// headerImageUrl: 'https://picsum.photos/250?image=9',
// code: element['label'],
// groupCode: element['zip'],
// );
// }).toList(),
// canPop: false,
// onSelectedData: (ContactorDataListData data) {
// print('${data.toString()}');
// },
// ),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: () {
ContactorPicker.showPicker(
context,
showGroupCode: true,
dataList: DataUtil.dataList.map((element) {
String pinyin = PinyinHelper.getPinyinE(element['name'],
separator: "",
defPinyin: '#',
format: PinyinFormat.WITHOUT_TONE);
return ContactorDataListData(
name: element['name'],
id: int.tryParse(element['zip']),
pinyin: pinyin,
// headerImageUrl: 'https://picsum.photos/250?image=9',
code: element['label'],
groupCode: element['zip'],
);
}).toList(),
title: '地址簿',
extendWidget: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
alignment: Alignment.centerLeft,
height: 40,
child: Text('666666'),
),
Container(
height: 40,
alignment: Alignment.centerLeft,
child: Text('555555'),
),
Expanded(
child: Container(
height: 40,
alignment: Alignment.centerLeft,
child: Text('888888'),
),
)
],
),
// backgroundColor: Color(0xFFFAFAFA),
letterSelectedColor: Colors.blueAccent,
onSelectedData: (data, pageNum) {
print(data.toJson());
_currentData = data.toJson().toString();
setState(() {});
},
);
},
child: Text('地址簿'),
),
TextButton(
onPressed: () {
ContactorPicker.showSearchPicker(
context,
showGroupCode: true,
dataList: DataUtil.dataList.map((element) {
String pinyin = PinyinHelper.getPinyinE(element['name'],
separator: " ",
defPinyin: '#',
format: PinyinFormat.WITHOUT_TONE);
return ContactorDataListData(
name: element['name'],
id: int.tryParse(element['zip']),
pinyin: pinyin,
code: element['label'],
groupCode: element['zip'],
);
}).toList(),
backgroundColor: Color(0xFFFAFAFA),
onSelectedData: (data, pageNum) {
print(data.toJson());
_currentData = data.toJson().toString();
setState(() {});
},
);
},
child: Text('搜索'),
),
Container(
padding: EdgeInsets.symmetric(horizontal: 30),
child: Text('currentData: $_currentData\n'),
),
],
),
),
);
}
}
Download Details:
Author: shinenyok
Source Code: https://github.com/shinenyok/contactor_picker
1657444685
Language: English
city_pickers
中国的城市三级联动选择器
Demo
沟通QQ群
QQ 群号码: 935915271
开始
在flutter的项目文件中增加依赖
dependencies:
...
city_pickers:^0.0.1
关于如何运行flutter项目, 参考官方文档documentation.
使用方法
Import city_pickers.dart
import 'package:zxj_city_pickers/city_pickers.dart';
简单使用方法
...
// type 1
Result result = await CityPickers.showCityPicker(
context: context,
);
// type 2
Result result2 = await CityPickers.showFullPageCityPicker(
context: context,
);
// type 3
Result result2 = await CityPickers.showCitiesSelector(
context: context,
);
Name | Type | Desc |
---|---|---|
showCityPicker | Function | 呼出弹出层,显示多级选择器 |
showFullPageCityPicker | Function | 呼出一层界面, 显示多级选择器 |
showCitiesSelector | Function | 呼出一层, 显示支持字母定位城市选择器 |
utils | Function | 获取utils接口的钩子 |
Name | Type | Default | Desc |
---|---|---|---|
context | BuildContext | 上下文对象 | |
theme | ThemeData | Theme.of(context) | 主题, 可以自定义 |
locationCode | String | 110000 | 初始化地址信息, 可以是省, 市, 区的地区码 |
height | double | 300 | 弹出层的高度, 过高或者过低会导致容器报错 |
showType | ShowType | ShowType.pca | 三级联动, 显示类型 |
barrierOpacity | double | 0.5 | 弹出层的背景透明度, 应该是大于0, 小于1 |
barrierDismissible | bool | true | 是否可以通过点击弹出层背景, 关闭弹出层 |
cancelWidget | Widget | 用户自定义取消按钮 | |
confirmWidget | Widget | 用户自定义确认按钮 | |
itemExtent | double | 目标框高度 | |
itemBuilder | Widget | item生成器, function(String value, List | |
citiesData | Map | 城市数据 | 选择器的城市与区的数据源 |
provincesData | Map | 省份数据 | 选择器的省份数据源 |
Name | Type | Default | Desc |
---|---|---|---|
context | BuildContext | null | 上下文对象 |
theme | ThemeData | Theme.of(context) | 主题, 可以自定义 |
locationCode | String | 110000 | 初始化地址信息, 可以是省, 市, 区的地区码 |
showType | ShowType | ShowType.pca | 三级联动, 显示类型 |
|citiesData|Map|城市数据|选择器的城市与区的数据源| |provincesData|Map|省份数据|选择器的省份数据源|
Name | Type | Default | Desc |
---|---|---|---|
context | BuildContext | null | 上下文对象 |
theme | ThemeData | Theme.of(context) | 主题, 可以自定义 |
locationCode | String | 110000 | 初始化地址信息, 可以是省, 市, 区的地区码 |
title | String | 城市选择器 | 弹出层界面标题 |
citiesData | Map | 城市数据 | 选择器的城市与区的数据源 |
provincesData | Map | 省份数据 | 选择器的省份数据源 |
hotCities | List<HotCity> | null | 热门城市 |
sideBarStyle | BaseStyle | 初始默认样式 | 右侧字母索引集样式 |
cityItemStyle | BaseStyle | 初始默认样式 | 城市选项样式 |
topStickStyle | BaseStyle | 初始默认样式 | 顶部索引吸顶样式 |
utils 是用来封装常用的一些方法, 方便使用者能更好的使用该插件. 使用者通过以下方式声明实例, 可以获取所有的工具类方法
// 声明实例
CityPickerUtil cityPickerUtils = CityPickers.utils();
使用者通过地区ID, 获取所在区域的省市县等相关信息. 当未查询到具体信息. 返回空的Result对象.
print('result>>> ${cityPickerUtils.getAreaResultByCode('100100)}');
// 输出为: result>>>> {"provinceName":"北京市","provinceId":"110000","cityName":"东城区","cityId":"110101"}
数据来源
声明
本项目Example部份代码与样式, 参考借鉴Flutter Go, flutter go 是flutter 开发者帮助 APP,包含 flutter 常用 140+ 组件的demo 演示与中文文档
Run this command:
With Flutter:
$ flutter pub add zxj_city_pickers
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
zxj_city_pickers: ^1.1.1
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:zxj_city_pickers/city_pickers.dart';
import 'package:zxj_city_pickers/meta/province.dart';
import 'package:zxj_city_pickers/modal/base_citys.dart';
import 'package:zxj_city_pickers/modal/point.dart';
import 'package:zxj_city_pickers/modal/result.dart';
Download Details:
Author:
Source Code: https://pub.dev/packages/zxj_city_pickers
1656831374
File Picker
A package that allows you to use the native file explorer to pick single or multiple files, with extensions filtering support.
Uint8List
) if needed;If you have any feature that you want to see in this package, please feel free to issue a suggestion. 🎉
API | Android | iOS | Linux | macOS | Windows | Web |
---|---|---|---|---|---|---|
clearTemporaryFiles() | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
getDirectoryPath() | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
pickFiles() | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
saveFile() | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ |
See the API section of the File Picker Wiki or the official API reference on pub.dev for further details.
See the File Picker Wiki for every detail on about how to install, setup and use it.
Quick simple usage example:
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
File file = File(result.files.single.path);
} else {
// User canceled the picker
}
FilePickerResult? result = await FilePicker.platform.pickFiles(allowMultiple: true);
if (result != null) {
List<File> files = result.paths.map((path) => File(path)).toList();
} else {
// User canceled the picker
}
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['jpg', 'pdf', 'doc'],
);
String? selectedDirectory = await FilePicker.platform.getDirectoryPath();
if (selectedDirectory == null) {
// User canceled the picker
}
String? outputFile = await FilePicker.platform.saveFile(
dialogTitle: 'Please select an output file:',
fileName: 'output-file.pdf',
);
if (outputFile == null) {
// User canceled the picker
}
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
PlatformFile file = result.files.first;
print(file.name);
print(file.bytes);
print(file.size);
print(file.extension);
print(file.path);
} else {
// User canceled the picker
}
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
Uint8List fileBytes = result.files.first.bytes;
String fileName = result.files.first.name;
// Upload file
await FirebaseStorage.instance.ref('uploads/$fileName').putData(fileBytes);
}
For full usage details refer to the Wiki above.
For help getting started with Flutter, view our online documentation.
For help on editing plugin code, view the documentation.
Run this command:
With Flutter:
$ flutter pub add pfile_picker
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
pfile_picker: ^4.5.1+3
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:pfile_picker/pfile_picker.dart';
import 'src/file_picker_demo.dart';
import 'package:flutter/widgets.dart';
void main() => runApp(FilePickerDemo());
Download Details:
Author: miguelpruivo
Source Code: https://github.com/miguelpruivo/flutter_file_picker
1655053817
由于地址选择的数据来源会更新,为了统一,在后台配置一份城市数据,前端获取,否则各个平台都配置一份数据,维护会很麻烦,而且有可能每个平台城市的数据结构都不一样。 本库就是由此而来,数据从后台实时获取,只要解析成固定的数据结构就可以
dependencies:
flutter_city_picker: ^1.0.4
CityPicker.show(context: context, cityPickerListener: this);
CityPicker.show(
context: context,
// 主题颜色
theme: ThemeData(
// 弹窗的背景颜色
dialogBackgroundColor: Colors.white,
),
// 底部弹出框动画时间
duration: 200,
// 背景透明度
opacity: 0.5,
// 点击外部是否消失
dismissible: true,
// 高度
height: 400,
// 标题高度
titleHeight: 50,
// 顶部圆角
corner: 20,
// 距离左边的间距
paddingLeft: 15,
// 标题组件
titleWidget: Container(
padding: EdgeInsets.only(left: 15),
child: Text(
'请选择地址',
style: TextStyle(
color: Colors.black54,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
// 关闭图标组件
closeWidget: Icon(Icons.close),
// tab 高度
tabHeight: 40,
// 是否启用街道
enableStreet: _showStreet,
// 是否显示指示器
showTabIndicator: _showTabIndicator,
// tab 指示器颜色
tabIndicatorColor: Theme.of(context).primaryColor,
// tab 指示器高度
tabIndicatorHeight: 2,
// tab 字体大小
labelTextSize: 15,
// tab 选中的字体颜色
selectedLabelColor: Theme.of(context).primaryColor,
// tab 未选中的字体颜色
unselectedLabelColor: Colors.black54,
// 列表 item 头部高度
itemHeadHeight: 30,
// 列表 item 头部背景颜色
itemHeadBackgroundColor: Colors.white,
// 列表 item 头部分割线颜色
itemHeadLineColor: Colors.black,
// 列表 item 头部分割线高度
itemHeadLineHeight: 0.1,
// 列表 item 头部文字样式
itemHeadTextStyle: TextStyle(fontSize: 15, color: Colors.black),
// 列表 item 高度
itemHeight: 40,
// 索引组件宽度
indexBarWidth: 28,
// 索引组件 item 高度
indexBarItemHeight: 20,
// 索引组件背景颜色
indexBarBackgroundColor: Colors.black12,
// 索引组件文字样式
indexBarTextStyle: TextStyle(fontSize: 14, color: Colors.black54),
// 列表选中的图标组件
itemSelectedIconWidget:
Icon(Icons.done, color: Theme.of(context).primaryColor, size: 16),
// 列表选中的文字样式
itemSelectedTextStyle: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
color: Theme.of(context).primaryColor),
// 列表未选中的文字样式
itemUnSelectedTextStyle: TextStyle(fontSize: 14, color: Colors.black54),
cityPickerListener: this,
);
<你的组件> implements CityPickerListener
@override
Future<List<City>> loadProvinceData() async {
// 发起网络请求,获取省级数据
return 返回省级数据;
}
@override
Future<List<City>> onProvinceSelected(String provinceCode, String provinceName) async {
// 点击省份后的回调,根据城市代码或名称去请求市级数据
return 返回市级数据;
}
@override
Future<List<City>> onCitySelected(String cityCode, String cityName) async {
// 点击城市后的回调,根据城市代码或名称去请求区级数据
return 返回区级数据;
}
@override
Future<List<City>> onDistrictSelected(String districtCode, String districtName) {
// 点击区后的回调,根据城市代码或名称去请求街道数据
return 返回街道数据;
}
@override
void onFinish(String provinceCode, String provinceName, String cityCode,
String cityName, String districtCode, String districtName, String streetCode, String streetName) {
// 最终回调,返回省市区的代码和名称
setState(() {
_address = provinceName + " " + cityName + " " + districtName + " " + streetName;
});
}
无
欢迎提 PR 或者 ISSUE
Run this command:
With Flutter:
$ flutter pub add flutter_city_picker
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
flutter_city_picker: ^1.0.4
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:flutter_city_picker/city_picker.dart';
import 'package:flutter_city_picker/listener/item_listener.dart';
import 'package:flutter_city_picker/listener/picker_listener.dart';
import 'package:flutter_city_picker/model/city.dart';
import 'package:flutter_city_picker/model/section_city.dart';
import 'package:flutter_city_picker/model/tab.dart';
import 'package:flutter_city_picker/view/city_picker.dart';
import 'package:flutter_city_picker/view/inherited_widget.dart';
import 'package:flutter_city_picker/view/item_widget.dart';
import 'package:flutter_city_picker/view/layout_delegate.dart';
import 'package:flutter_city_picker/view/listview_section.dart';
import 'package:flutter_city_picker/view/popup_route.dart';
import 'dart:async';
import 'package:city_picker_example/http/http_util.dart';
import 'package:flutter/material.dart';
import 'package:flutter_city_picker/city_picker.dart';
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
import 'package:provider/provider.dart';
import 'provider/theme_provider.dart';
import 'view/item_text.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider.value(value: ThemeProvider()),
],
child: Consumer<ThemeProvider>(
builder: (context, themeProvider, _) {
Color color = themeProvider.themeColor;
return MaterialApp(
title: 'CityPickerExample',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: color,
dialogBackgroundColor: Colors.white,
),
home: HomeWidget(),
);
},
),
);
}
}
class HomeWidget extends StatefulWidget {
@override
HomeWidgetState createState() => HomeWidgetState();
}
class HomeWidgetState extends State<HomeWidget> implements CityPickerListener {
String _address = "请选择地区";
Color _themeColor = Colors.blue;
Color _backgroundColor = Colors.white;
double _height = 400.0;
double _opacity = 0.5;
double _corner = 20;
bool _dismissible = true;
bool _showTabIndicator = true;
bool _showStreet = false;
@override
void initState() {
super.initState();
}
void show() {
CityPicker.show(
context: context,
theme: ThemeData(
dialogBackgroundColor: _backgroundColor,
),
duration: 200,
opacity: _opacity,
dismissible: _dismissible,
height: _height,
titleHeight: 50,
corner: _corner,
paddingLeft: 15,
titleWidget: Container(
padding: EdgeInsets.only(left: 15),
child: Text(
'请选择地址',
style: TextStyle(
color: Colors.black54,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
closeWidget: Icon(Icons.close),
tabHeight: 40,
enableStreet: _showStreet,
showTabIndicator: _showTabIndicator,
tabIndicatorColor: Theme.of(context).primaryColor,
tabIndicatorHeight: 2,
labelTextSize: 15,
selectedLabelColor: Theme.of(context).primaryColor,
unselectedLabelColor: Colors.black54,
itemHeadHeight: 30,
itemHeadLineColor: Colors.black,
itemHeadLineHeight: 0.1,
itemHeadTextStyle: TextStyle(fontSize: 15, color: Colors.black),
itemHeight: 40,
indexBarWidth: 28,
indexBarItemHeight: 20,
indexBarBackgroundColor: Colors.black12,
indexBarTextStyle: TextStyle(fontSize: 14, color: Colors.black54),
itemSelectedIconWidget:
Icon(Icons.done, color: Theme.of(context).primaryColor, size: 16),
itemSelectedTextStyle: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
color: Theme.of(context).primaryColor),
itemUnSelectedTextStyle: TextStyle(fontSize: 14, color: Colors.black54),
cityPickerListener: this,
);
}
Widget _buildTheme() {
return InkWell(
onTap: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('选择颜色'),
content: SingleChildScrollView(
child: BlockPicker(
pickerColor: _themeColor,
onColorChanged: (color) {
setState(() {
_themeColor = color;
});
Provider.of<ThemeProvider>(context, listen: false)
.setTheme(color);
},
),
),
);
},
);
},
child: Container(
color: _themeColor,
width: double.infinity,
padding: EdgeInsets.all(10),
margin: EdgeInsets.fromLTRB(80, 10, 80, 10),
),
);
}
Widget _buildColor() {
return InkWell(
onTap: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('选择颜色'),
content: SingleChildScrollView(
child: BlockPicker(
pickerColor: _backgroundColor,
onColorChanged: (color) {
setState(() {
_backgroundColor = color;
});
},
),
),
);
},
);
},
child: Container(
color: _backgroundColor,
width: double.infinity,
padding: EdgeInsets.all(10),
margin: EdgeInsets.fromLTRB(80, 10, 80, 10),
),
);
}
Widget _buildOpacity() {
return Row(
children: <Widget>[
Expanded(
flex: 1,
child: Slider(
value: _opacity,
min: 0.01,
max: 1.0,
divisions: 100,
activeColor: Theme.of(context).primaryColor,
inactiveColor: Colors.grey,
onChanged: (double) {
setState(() {
_opacity = double.toDouble();
});
},
),
),
Text("${_opacity.toStringAsFixed(2)}")
],
);
}
Widget _buildDismissible() {
return Container(
alignment: Alignment.centerRight,
child: Switch(
value: _dismissible,
activeColor: Theme.of(context).primaryColor,
onChanged: (bool val) {
setState(() {
_dismissible = !_dismissible;
});
},
));
}
Widget _buildHeight() {
return Row(
children: <Widget>[
Expanded(
flex: 1,
child: Slider(
value: _height,
min: 200,
max: 500,
divisions: 100,
activeColor: Theme.of(context).primaryColor,
inactiveColor: Colors.grey,
onChanged: (double) {
setState(() {
_height = double.toDouble();
});
},
),
),
Text("${_height.toStringAsFixed(2)}")
],
);
}
Widget _buildCorner() {
return Row(
children: <Widget>[
Expanded(
flex: 1,
child: Slider(
value: _corner,
min: 0.0,
max: 30,
divisions: 100,
activeColor: Theme.of(context).primaryColor,
inactiveColor: Colors.grey,
onChanged: (double) {
setState(() {
_corner = double.toDouble();
});
},
),
),
Text("${_corner.toStringAsFixed(2)}")
],
);
}
Widget _buildIndicator() {
return Container(
alignment: Alignment.centerRight,
child: Switch(
value: _showTabIndicator,
activeColor: Theme.of(context).primaryColor,
onChanged: (bool val) {
setState(() {
_showTabIndicator = !_showTabIndicator;
});
},
));
}
Widget _buildStreet() {
return Container(
alignment: Alignment.centerRight,
child: Switch(
value: _showStreet,
activeColor: Theme.of(context).primaryColor,
onChanged: (bool val) {
setState(() {
_showStreet = !_showStreet;
});
},
));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('城市选择器'),
backgroundColor: Theme.of(context).primaryColor,
),
body: SingleChildScrollView(
child: Column(
children: [
ItemTextWidget(
title: '选择城市',
subWidget: InkWell(
onTap: () => show(),
child: Padding(
padding: EdgeInsets.fromLTRB(0, 15, 0, 15),
child: Text(_address),
),
),
),
ItemTextWidget(title: '主题颜色', subWidget: _buildTheme()),
ItemTextWidget(title: '透明度', subWidget: _buildOpacity()),
ItemTextWidget(title: '外部点击消失', subWidget: _buildDismissible()),
ItemTextWidget(title: '弹窗背景颜色', subWidget: _buildColor()),
ItemTextWidget(title: '弹窗高度', subWidget: _buildHeight()),
ItemTextWidget(title: '顶部圆角', subWidget: _buildCorner()),
ItemTextWidget(title: '显示 Indicator', subWidget: _buildIndicator()),
ItemTextWidget(title: '开启第四级街道', subWidget: _buildStreet()),
],
),
),
);
}
@override
Future<List<City>> loadProvinceData() async {
print("loadProvinceData");
return HttpUtils.getCityData("");
}
@override
Future<List<City>> onProvinceSelected(
String? provinceCode, String? provinceName) async {
print("onProvinceSelected --- provinceName: $provinceName");
return HttpUtils.getCityData(provinceName!);
}
@override
Future<List<City>> onCitySelected(String? cityCode, String? cityName) async {
print("onCitySelected --- cityName: $cityName");
return HttpUtils.getCityData(cityName!);
}
@override
Future<List<City>> onDistrictSelected(
String? districtCode, String? districtName) {
print("onDistrictSelected --- districtName: $districtName");
return HttpUtils.getCityData(districtName!);
}
@override
void onFinish(
String? provinceCode,
String? provinceName,
String? cityCode,
String? cityName,
String? districtCode,
String? districtName,
String? streetCode,
String? streetName) {
print("onFinish");
setState(() {
_address = provinceName! +
" " +
cityName! +
" " +
districtName! +
" " +
streetName!;
});
}
}
Download Details:
Author: wenchaosong
Source Code: https://github.com/wenchaosong/FlutterCityPicker