学习笔记| AS入门(五) 高级控件篇(下)

以下是今日份的控件清单:

  • WebView 网络视图
  • Dialog 对话框
  • Notification 通知
  • Meau 菜单

1.WebView 网络视图

当一个应用程序想展示一个网页时,可以怎么做呢?自己去做一个浏览器是完全没有必要的,一种方法是调用系统浏览器或第三方浏览器加载,需要用到Activity篇学过的信使Intent类。Intent不仅可以启动程序内部的活动,也可以启动其他程序的活动,所以可以调用其他浏览器去帮忙去打开一个网站。具体代码如下:

这里首先指定该Intent的action是Intent.ACTION_VIEW,这是一个Android系统内置的动作,其常量值为android.intent.action.VIEW。然后通过Uri.parse()方法,将一个网址字符串解析成一个Uri对象,再调用Intent的setData()方法将这个Uri对象传递进去,最后启动活动。运行之后:

还有一种方法就是使用系统提供的WebView控件,借助它可以在应用程序里嵌入一个浏览器,就能加载显示网页了。如何做到的呢?一起来学习一下,先在布局里放入WebView并铺满全屏:

之后在MainActivity里获取这个WebView实例并做一系列的设置。用WebView的loadUrl()方法可直接传入网址;然后调用它的getSettings()方法去设置一些浏览器的属性,这里只是用setJavascriptEnable(true)让WebView支持Javascript脚本;接下来需要处理页面导航,它的作用是在处理一个WebView中的页面链接时,覆盖系统用默认的浏览器打开和加载目标URL的这一行为,而使之能在WebView中打开。具体代码见下:

为了给用户一个良好的体验,在WebView加载网页的过程中加一个ProgressDialog。实现方法是调用它的setWebChromeClient()方法并传入一个WebChromeClient实例,而需要重写的onProgressChanged()方法里正好返回当前进度数据newProgress,利用它就可以去做一个实时显示加载进度的ProgressDialog了。上篇学过了ProgressDialog下面这些代码肯定非常熟悉了:

最后一定要在配置文件获取网络权限。不知你是否发现,在前一种方法调用系统自带的浏览器或第三方浏览器是不需要设置网络权限的,这点要注意。

运行一下程序看看效果:

2.Dialog 对话框

对话框是在当前界面弹出的一个小窗口,可用于显示重要的提示信息并让用户确认信息,比如上一篇讲过的DataPickerDialog和TimePickerDialog,也可显示某种状态,比如ProgressDialog。一般情况下需要用户与之交互然后返回到原活动界面。从之前接触过的Dialog会发现,它需要我们在代码中直接创建然后show()出来。而不同于学过的Dialog,今天要学习的下图所展示的这一系列Dialog都是用Builder建立得到的,掌握一个其他就不在话下,在布局中准备好五个按钮一起来学习吧。

对五个按钮都注册监听事件,每个对话框一开始都要实例化一个AlertDialog.Builder对象,然后在它身上set各种属性,有关图标、标题和内容等设计在之前的学习都有涉及,接下来主要学习每个Dialog独特的按钮。一切都设set好之后,用Builder的create()方法就能得到一个Dialog,最后一定要把对话框show()出来。下面分别学习每个Dialog不同的地方:

(1)确认对话框

这里做一个确认是否退出应用的Dialog,用setPositiveButton()setNegativeButton()方法添加确定和取消按钮,都用到
DialogInterface下的OnClickListener监听器,点击确认就finish()退出应用,否则打印一段Toast。

效果如下:

(2)单选对话框

setSingleChoiceItems()为单选对话框设置展示的数据、初始选中项(从0计算)以及监听选项是否被点击的OnClickListener,上述一一对应所需的三个参数。

效果如下:

(3)多选对话框

多选对话框和单选对话框就非常相似了,不同的是用setMultiChoiceItems()OnMultiChoiceClickListener

(4)列表对话框

列表对话框用setItems()提供数据源和监听器OnClickListener

效果如下:

(5)自定义对话框

既然是自定义样式,不妨自定义布局里有一张图片和一段文本吧!如下图:

在代码里首先利用LayoutInflater类将刚刚自定义的布局动态加载到当前布局得到一个View,再把这个View用Builder的setView()传入到对话框布局里就可以了。

效果如图:

3.Notification 通知

Notification是显示在手机状态栏的消息,在手机最顶端。将Notification放在控件篇因为它的创建方法和上面的Dialog有异曲同工之妙,也要利用Builder建立得到,所以索性给一点篇幅来学习如何发送和取消一个通知 。下图是这个小demo的布局,有两个按钮一个发送一个取消:

首先来看一个通知包含哪些内容:图标(SmallIcon)、标题(ContextTitle)、内容(ContextText)、时间(When)还有点击后的响应。那么下面就实例化一个NotificationCompat.Builder然后set这些属性吧!

下图红框内就是构造一个Notification的过程。除了上面的几个属性,为了更好的告知用户通知到来还可以设置手机做一些效果,比如震动、有提示声音还有LED灯亮起。这里给值DEFAULT_ALL表示以上三个效果都设置。

还有一个关键,如何实现点击响应。这需要用到PendingIntent类,它看起来就和Intent有些相似,它们都是可指明一个意图并执行一些任务,只不过前者不是立即去做,还是在合适的时间才执行。这里我们想让这个通知跳转到Dialog那个活动界面,所以调用PendingIntent.getActivity()并提供(提供上下文、请求码、实现页面跳转的Intent、被访问码)四个参数,就会得到一个PendingIntent实例,再传入Builder的setContentIntent()里,跳转就可以实现了。最后用Builder的build()就能得到一个Notification了。

但还没结束,Notification自己并不能去发送,需要用由系统提供的管理类NotificationManager去完成发送和取消通知的事情,它有两个方法,发送通知notify(被发送通知的id,通知对象)和取消发送cancel(被取消发送的通知id)。获取一个NotificationManager对象方法见下图:

当用户点击通知页面跳转后,就可以将系统状态栏上的通知取消了。在跳转后的活动里同样调用NotificationManager的cancel()方法就可以了。到此整个需求就实现了。

最后一定注意手机震动需要权限。

运行程序,下图展示了一个Notification从发出到被点击到取消的整个过程:

注意:安卓8.0发通知需要为通知添加渠道NotificationChannel,详见Android 8.0 通知显示

4.Meau 菜单

菜单是许多应用程序不可或缺的一部分,这里主要介绍下面三种菜单。

1) 选项菜单 OptionsMenu:android中最常规的菜单,每个Activity只有一个选项菜单。
2) 子菜单SubMenu:android中点击子菜单将弹出悬浮窗口显示子菜单项,用于把功能相近的菜单分组显示。
3) 上下文菜单ContextMenu:android中长按视图控件后出现的菜单,每个View都可有一个上下文菜单,一般常用于ListView和GridView。

(1)菜单的创建
创建一张菜单有两种方法,第一种通过加载xml文件的菜单项。但是菜单的布局文件并不是在res->layout文件夹下,而要在res下新建名为menu的文件夹,这里才是菜单xml文件的容身之地。详细步骤见图:

之后就可以根据需求在布局文件里添加菜单项Item,并指定每个Item的id和title。三种菜单的布局和样式效果如下图:

有了布局,就可以在需要菜单的Activity里重写方法 onCreate某某某()并加入一行代码getMenuInflater().inflate(需要添加的菜单布局,menu)就可以了。对应关系是:添加选项菜单或子菜单就重写onCreateOptionsMenu()方法,添加上下文菜单就重写onCreateContextMenu()方法。

例如添加一个ContextMenu:

第二种方法是直接在被重写的方法里用代码动态添加,方法是menu.add()并提供四个参数(groupId,itemId,order,title), 其中itemId和title对应了xml中Item的id和title,groupId用来分组的Id,order是菜单项用来排序的。menu还可以set菜单其他属性,如图标、标题,在后面代码中有展示。

三种菜单两种添加方式的代码如下图所示:

这里强调一点,因为ContextMenu对应的是每个View,这里以ListView为例,所以一定要给ListView注册上ContextMenu。代码见下:

(2)菜单项的监听

当然每个菜单项可以设置点击响应事件,事件会返回参数菜单项item,再利用item.getGroupId()item.getItemId()就能判断被点击菜单项并设置相应的动作了。

例如在SubMenu设置点击事件方法:

点击效果:

下表展示三种菜单各自对应方法。

至此高级控件篇就告一段落了,Android还提供很多控件,我们也可以按照自己的需求自定义控件,这些内容在将来学习中继续慢慢探索吧!

> 下一篇内容:碎片Fragment