拨打电话的功能在app里也很常见,比如一般的外卖app都会有这个才做。其实Flutter本身是没给我们提供拨打电话的能力的,那我们如何来拨打电话那?

1、编写店长电话模块

这个小伙伴们一定轻车熟路了,我也就不再多介绍吧。直接看代码,相信都能看懂。

class LeaderPhone extends StatelessWidget {
final String leaderImage; 店长图片
final String leaderPhone; 店长电话 LeaderPhone({Key key, this.leaderImage,this.leaderPhone}) : super(key: key); @override
Widget build(BuildContext context) {
return Container(
child: InkWell(
onTap: (){},
child: Image.network(leaderImage),
),
);
}
}

2、获取需要的数据

在HomePage里获取获取店长图片和电话数据,并形成变量。

String  leaderImage= data['data']['shopInfo']['leaderImage'];  //店长图片
String leaderPhone = data['data']['shopInfo']['leaderPhone']; //店长电话

有了数据之后,就可以调用这个自己写的组件了。调用方法如下:

LeaderPhone(leaderImage:leaderImage,leaderPhone: leaderPhone)  广告组件

3、url_launcher的简介

官方介绍:

A Flutter plugin for launching a URL in the mobile platform. Supports iOS and Android.

意思是用于在移动平台中启动URL的Flutter插件,适用于IOS和Android平台。他可以打开网页,发送邮件,还可以拨打电话。

github地址:https://github.com/flutter/plugins/tree/master/packages/url_launcher

引入依赖

在pubspec.yaml文件里注册依赖,并保存下载包。请注意使用最新版。

url_launcher: ^5.0.1

在需要使用的页面在使用import引入具体的url_launcher包。

import 'package:url_launcher/url_launcher.dart';

4、改造店长电话组件

有了url_launcher插件就后,我们就可以实现拨打电话功能了,不过要简单的改造一下拨打电话模块的代码,改造后的代码如下。

class LeaderPhone extends StatelessWidget {
final String leaderImage; 店长图片
final String leaderPhone; 店长电话 LeaderPhone({Key key, this.leaderImage,this.leaderPhone}) : super(key: key); @override
Widget build(BuildContext context) {
return Container(
child: InkWell(
onTap:_launchURL,
child: Image.network(leaderImage),
),
);
} void _launchURL() async {
String url = 'tel:'+leaderPhone;
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
}

全部代码:

import 'dart:convert';

import 'package:flutter/material.dart';
import '../service/service_method.dart';
import 'package:flutter_swiper/flutter_swiper.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:url_launcher/url_launcher.dart'; class HomePage extends StatefulWidget {
_HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { String homePageContent='正在获取数据'; @override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('百姓生活+'),
),
body:FutureBuilder(
future: getHomePageContent(),
builder: (context,snapshot){
if(snapshot.hasData){
var data = json.decode(snapshot.data.toString());
List<Map> swiper = (data['data']['slides'] as List).cast();
List<Map> navigatorList = (data['data']['category'] as List).cast(); 类别列表
String advertesPicture = data['data']['advertesPicture']['PICTURE_ADDRESS']; 广告图片
String leaderImage= data['data']['shopInfo']['leaderImage']; 店长图片
String leaderPhone = data['data']['shopInfo']['leaderPhone']; 店长电话
return Column(
children: <Widget>[
SwiperDiy(swiperDataList: swiper,),
TopNavigator(navigatorList: navigatorList,),
AdBanner(adbanner: advertesPicture,),
LeaderPhone(leaderImage: leaderImage,leaderPhone: leaderPhone,) ],
);
}else{
return Center(
child: Text("加载中"),
);
}
},
)
);
}
} // 轮播组件
class SwiperDiy extends StatelessWidget { final List swiperDataList; SwiperDiy({Key key,this.swiperDataList}):super(key:key); @override
Widget build(BuildContext context) {
ScreenUtil.instance = ScreenUtil(width: 750,height: 1334)..init(context);
return Container(
height: ScreenUtil().setHeight(333),
width: ScreenUtil().setWidth(750),
child: Swiper(
itemCount: swiperDataList.length,
itemBuilder: (BuildContext context,int index){
return Image.network("${swiperDataList[index]['image']}",fit:BoxFit.fill);
},
pagination: SwiperPagination(),
autoplay: true,
),
);
}
} // 顶部导航
class TopNavigator extends StatelessWidget { final List navigatorList; TopNavigator({this.navigatorList}); Widget _gradViewItemUi(BuildContext context,item){
return InkWell(
onTap: (){print("点击了导航");},
child: Column(
children: <Widget>[
Image.network(item['image'],width: ScreenUtil().setWidth(95),),
Text(item['mallCategoryName'])
],
),
);
} @override
Widget build(BuildContext context) { if(navigatorList.length>10){
navigatorList.removeRange(10, navigatorList.length);
} return Container(
height: ScreenUtil().setHeight(320),
padding: EdgeInsets.all(3.0),
child: GridView.count(
crossAxisCount: 5,
padding: EdgeInsets.all(4.0),
children: navigatorList.map((item){
return _gradViewItemUi(context, item);
}).toList(),
),
);
}
} // 广告条
class AdBanner extends StatelessWidget { String adbanner; AdBanner({this.adbanner}); @override
Widget build(BuildContext context) {
return Container(
child: Image.network(adbanner),
);
}
} // 拨打店长电话
class LeaderPhone extends StatelessWidget { final String leaderPhone;
final String leaderImage; LeaderPhone({this.leaderPhone,this.leaderImage}); @override
Widget build(BuildContext context) {
return Container(
child: InkWell(
onTap: _launchURL,
child: Image.network(leaderImage),
),
);
} void _launchURL() async {
String url = 'tel:'+leaderPhone;
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
}

效果如下图所示:

这时候就可以打开虚拟机进行调试了,需要说的是,有些虚拟机并出不来拨打电话的效果,如果你的虚拟机出不来这个效果,可以使用真机进行测试。

5、本节总结 :

本节主要学习了使用url_launcher来进行打开网页和拨打电话的设置。希望小伙伴们都有所收获。

Flutter移动电商实战 --(14)首页_拨打电话操作的更多相关文章

  1. Flutter移动电商实战 --(21)分类页_类别信息接口调试

    先解决一个坑 取消上面的GridVIew的回弹效果.就是在拖这个gridview的时候有一个滚动的效果 physics: NeverScrollableScrollPhysics(), 大R刷新后,点 ...

  2. Flutter移动电商实战 --(43)详细页_补充首页跳转到详细页

    首页轮播点击到详细页 修改我们轮播这里的代码:SwiperDiy这个类这里的代码 return InkWell( onTap: (){ Application.router.navigateTo(co ...

  3. Flutter移动电商实战 --(19)首页_火爆专区商品接口制作

    Dart中可选参数的设置 上节课在作通用方法的时候,我们的参数使用了一个必选参数,其实我们可以使用一个可选参数.Dart中的可选参数,直接使用“{}”(大括号)就可以了.可选参数在调用的时候必须使用p ...

  4. Flutter移动电商实战 --(11)首页_屏幕适配方案和制作

    1.flutter_ScreenUtil插件简介 flutter_ScreenUtil屏幕适配方案,让你的UI在不同尺寸的屏幕上都能显示合理的布局. 插件会让你先设置一个UI稿的尺寸,他会根据这个尺寸 ...

  5. Flutter移动电商实战 --(18)首页_火爆专区商品接口制作

    1.获取接口的方法 在service/service_method.dart里制作方法.我们先不接收参数,先把接口调通. Future getHomePageBeloConten() async{ t ...

  6. Flutter移动电商实战 --(17)首页_楼层区域的编写

    1.楼层标题组件 该组件非常简单,只接收一个图片地址,然后显示即可: class FloorTitle extends StatelessWidget { final String picture_a ...

  7. Flutter移动电商实战 --(44)详细页_首屏自定义Widget编写

    把详细页的图片.标题.编号和价格形成一个单独的widget去引用 详情页的顶部单独封装个插件 在pages下面新建detials_page的文件件并在里面新建页面details_top_area.da ...

  8. Flutter移动电商实战 --(35)列表页_上拉加载更多制作

    右侧列表上拉加载配合类别的切换 上拉加载需要一个page参数,当点击大类或者小类的时候,这个page就要变成1 provide内定义参数 首先我们需要定义一个page的变量 下图是我们之前在首页的时候 ...

  9. Flutter移动电商实战 --(30)列表页_商品列表UI界面布局

    小程序里面的布局方式 小程序的图片上这里使用的是warp布局,因为首页里面火爆专区,已经用过了warp来布局了. 所以这里我们没有必要再讲一遍,这里我们使用ListView,我们把它布局成下图这种形式 ...

随机推荐

  1. ccs编译.lib

    新建 New一个CCS Project Output type选择"Static Library" 添加源文件 右击工程 -> Add Files- 编译 编译生成的.lib ...

  2. Vue获取数据渲染完成事件

    主要代码是这两坨 this.nextTick(function(){ alert('数据已经更新') }); this.$nextTick(function(){ alert('v-for渲染已经完成 ...

  3. 【Distributed】分布式配置中心

    一.概述 1.1 什么是分布式配置中心 常用分布式配置中心框架 二.Apollo阿波罗 2.1 Apollo特点 2.2 Apollo整体架构原理 2.3 Apollo Portol 环境搭建 Lin ...

  4. Mongo db 简单介绍及命令笔记

    首先来了解下什么是MongoDB ? MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统. 在高负载的情况下,添加更多的节点,可以保证服务器性能. MongoDB 旨在为W ...

  5. python学习之文件读写,序列化(json,pickle,shelve)

    python基础 文件读写 凡是读写文件,所有格式类型都是字符串形式传输 只读模式(默认) r  f=open('a.txt','r')#文件不存在会报错 print(f.read())#获取到文件所 ...

  6. Socket嵌套字通讯

    一.socket是什么 Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后 ...

  7. Java锁--LockSupport

    转载请注明出处:http://www.cnblogs.com/skywang12345/p/3505784.html LockSupport介绍 LockSupport是用来创建锁和其他同步类的基本线 ...

  8. Linux-删除文件空间不释放问题解决

    场景描述: 收到zabbix监控报警,晋中生产机器出现磁盘空间不足报警. 远程到该服务器,排查占员工磁盘空间的原因,发现tomcat日志过多,于是清除3天前的日志. 日志清理后,发现磁盘空间没有释放, ...

  9. login.exp

    #!/usr/bin/expect ] ] ] ] spawn ssh -p $user@$host expect { "*yes/no*" {send "yes\r&q ...

  10. 月球-I型,月份日历生成器----基于PHP7.3

    生成月份周日的类 <?php class mycalendar { function __construct($year,$mon) { $'; $this->firstday=strto ...