看过前一篇hello world类的Android开发入门文章《Hello Android!》,也许你一点成就感都没有,那么接下来我来分享我后续学习的过程,使用webview内嵌HTML、CSS和JS做一个简单的App。
先睹为快,如图,我们需要做一个随机选餐厅的应用,它有三个tab可以切换,一个选餐厅面板,一个添加餐厅面板,一个关于面板:
虽然很简陋,但是看起来像那么一回事,所有的界面都是用HTML和CSS实现的,JS实现标签切换和随机选餐厅功能,正如你做普通的页面一样,你要做的只是把页面放到Android的webview里。
编写App界面
按照之前文章里的步骤,我们只需添加一个webview控件,把它设置为填充父级和隐藏标题栏,也就是说除了状态栏,它已经是“全屏”的了,布局代码如下:
布局文件main.xml代码
1
2
3
4
5
6
7
8
9
10
11
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<LinearLayout xmlns
:
android
=
"http://schemas.android.com/apk/res/android"
android
:
orientation
=
"vertical"
android
:
layout_width
=
"fill_parent"
android
:
layout_height
=
"fill_parent"
>
<WebView android
:
layout_width
=
"fill_parent"
android
:
layout_height
=
"fill_parent"
android
:
id
=
"@+id/webViewMain"
>
</WebView>
</LinearLayout>
|
AndroidManifest.xml的application添加属性android:theme设置为无标题栏
1
2
3
4
5
6
7
8
9
10
|
<application android
:
label
=
"@string/app_name"
android
:
icon
=
"@drawable/ic_launcher"
android
:
theme
=
"@android:style/Theme.NoTitleBar"
>
<activity android
:
name
=
"what2eatActivity"
android
:
label
=
"@string/app_name"
android
:
screenOrientation
=
"portrait"
>
<intent-filter>
<action android
:
name
=
"android.intent.action.MAIN"
/>
<category android
:
name
=
"android.intent.category.LAUNCHER"
/>
</intent-filter>
</activity>
</application>
|
这样,Android控件就配置好了,接下来我们看看界面实现代码。
页面html结构:
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
|
<!DOCTYPE html>
<html>
<head>
<meta
charset
=
"UTF-8"
>
<title>
吃什么
</title>
<link
href
=
"themes/default.css"
rel
=
"stylesheet"
type
=
"text/css"
/>
<script type="text/javascript" src="scripts/zepto.min.js"></script>
<script type="text/javascript" src="scripts/app.js"></script>
</head>
<body>
<header>
<h1>
吃什么
</h1>
</header>
<footer>
<ul
id
=
"tabs"
class
=
"clearfix"
data
-tab
-ctrl
>
<li
class
=
"on"
>
<a
href
=
"#rock"
>
Rock
</a>
</li>
<li>
<a
href
=
"#add"
>
Add
</a>
</li>
<li>
<a
href
=
"#about"
>
About
</a>
</li>
</ul>
</footer>
<div
id
=
"rock"
data
-tab
-panel
>
<div
class
=
"wrapper"
>
<div data
-food
-list
>
</div>
<button
class
=
"run"
>
选餐厅
</button>
</div>
</div>
<div
id
=
"add"
data
-tab
-panel
>
<input
type
=
"text"
x
-webkit
-speech
/>
<div data
-food
-list
>
</div>
</div>
<div
id
=
"about"
data
-tab
-panel
>
<dl>
<dt>
使用帮助
</dt>
<dd>
<ul>
<li>
在Add面板可以自定义待抽签的项目;
</li>
<li>
Rock面板可以点击按钮开始选择,也可以摇一摇手机;
</li>
<li>
长按项目可以删除项目;
</li>
</ul>
</dd>
</dl>
</div>
<div
class
=
"del"
data
-popup
-del
>
<a
href
=
"#del"
>
</a>
</div>
</body>
</html>
|
样式编写:
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
/*
html5doctor.com Reset Stylesheet v1.6.1
Last Updated: 2010-09-17
Author: Richard Clark - http://richclarkdesign.com
*/
html, body, div, span, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
abbr, address, cite, code,
del, dfn, em, img, ins, kbd, q, samp,
small, strong, sub, sup, var,
b, i,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, figcaption, figure,
footer, header, hgroup, menu, nav, section, summary,
time, mark, audio, video
{
margin
:
0
;
padding
:
0
;
border
:
0
;
outline
:
0
;
font-size
:
100%
;
vertical-align
:
baseline
;
background
:
transparent
;
}
html,body
{
line-height
:
1
;
font-size
:
14px
;
}
article,aside,details,figcaption,figure,
footer,header,hgroup,menu,nav,section
{
display
:
block
;
}
ul
{
list-style
:
none
;
}
blockquote, q
{
quotes
:
none
;
}
blockquote:before, blockquote:after,
q:before, q:after
{
content
:
''
;
content
:
none
;
}
a
{
margin
:
0
;
padding
:
0
;
font-size
:
100%
;
vertical-align
:
baseline
;
background
:
transparent
;
text-decoration
:
none
;
}
/* change colours to suit your needs */
ins
{
background-color
:
#ff9
;
color
:
#000
;
text-decoration
:
none
;
}
/* change colours to suit your needs */
mark
{
background-color
:
#ff9
;
color
:
#000
;
font-style
:
italic
;
font-weight
:
bold
;
}
del
{
text-decoration
:
line-through
;
}
abbr[title], dfn[title]
{
border-bottom
:
1px
dotted
;
cursor
:
help
;
}
table
{
border-collapse
:
collapse
;
border-spacing
:
0
;
}
/* change border colour to suit your needs */
hr
{
display
:
block
;
height
:
1px
;
border
:
0
;
border-top
:
1px
solid
#cccccc
;
margin
:
1em
0
;
padding
:
0
;
}
input, select
{
vertical-align
:
middle
;
}
.clearfix:after
{
content
:
"\20"
;
display
:
block
;
height
:
0
;
clear
:
both
;
visibility
:
hidden
}
/*app theme start*/
@font-face {
font-family: 'icomoon';
src
:
url
(
'../fonts/icomoon.ttf'
)
format
(
'truetype'
)
,
url
(
'../fonts/icomoon.svg#icomoon'
)
format
(
'svg'
)
;
font-weight
:
normal
;
font-style
:
normal
;
}
body
{
background
:
#F3F9FC
;
color
:
#333
;
line-height
:
1.5em
;
}
header
{
background
:
#127FC0
;
color
:
white
;
font-size
:
1.5em
;
text-align
:
center
;
line-height
:
2.5em
;
}
footer
{
background
:
#127FC0
;
position
:
fixed
;
left
:
0
;
bottom
:
0
;
width
:
100%
;
box-shadow
:
0
-1px
5px
#333
;
}
ul[data-tab-ctrl] li
{
width
:
33.33333333%
;
float
:
left
;
line-height
:
4em
;
text-align
:
center
;
}
ul[data-tab-ctrl] li a
{
color
:
white
;
text-shadow
:
1px
1px
#333
;
font-size
:
1.6em
;
display
:
block
;
margin
:
5px
;
font-family
:
'icomoon'
;
}
ul[data-tab-ctrl] li.on a
{
background
:
#0D6194
;
border-radius
:
3px
;
box-shadow
:
0px
0px
10px
rgba
(
0,0,0,0.2
)
inset
;
}
div[data-tab-panel]
{
display
:
none
;
padding
:
10px
;
}
#add input
{
width
:
100%
;
color
:
#777
;
height
:
35px
;
border
:
1px
solid
#c7d0d2
;
border-radius
:
3px
;
}
#about dl dt
{
font-weight
:
bold
;
}
.wrapper
{
text-align
:
center
;
}
div[data-food-list]
{
text-align
:
left
;
}
div[data-food-list] li
{
display
:
inline-block
;
padding
:
10px
;
margin
:
5px
;
list-style-type
:
none
;
}
div[data-food-list] li.selected
{
background-color
:
#FA8E1A
;
color
:
#ffffff
;
}
.run
{
cursor
:
pointer
;
-moz-box-shadow
:
inset
0px
1px
0px
0px
#ffffff
;
-webkit-box-shadow
:
inset
0px
1px
0px
0px
#ffffff
;
box-shadow
:
inset
0px
1px
0px
0px
#ffffff
;
background
:
-webkit-gradient
(
linear,
left
top,
left
bottom,
color-stop
(
0.05,
#ededed
)
,
color-stop
(
1,
#dfdfdf
)
)
;
background
:
-moz-linear-gradient
(
center
top,
#ededed
5%,
#dfdfdf
100%
)
;
filter
:
progid
:
DXImageTransform.Microsoft.gradient
(
startColorstr
='#ededed',
endColorstr
='#dfdfdf'
)
;
background-color
:
#ededed
;
-moz-border-radius
:
6px
;
-webkit-border-radius
:
6px
;
border-radius
:
6px
;
border
:
1px
solid
#dcdcdc
;
display
:
inline-block
;
color
:
#777777
;
font-family
:
arial
;
font-size
:
15px
;
font-weight
:
bold
;
padding
:
16px
34px
;
text-decoration
:
none
;
text-shadow
:
1px
1px
0px
#ffffff
;
}
.run:hover
{
background
:
-webkit-gradient
(
linear,
left
top,
left
bottom,
color-stop
(
0.05,
#dfdfdf
)
,
color-stop
(
1,
#ededed
)
)
;
background
:
-moz-linear-gradient
(
center
top,
#dfdfdf
5%,
#ededed
100%
)
;
filter
:
progid
:
DXImageTransform.Microsoft.gradient
(
startColorstr
='#dfdfdf',
endColorstr
='#ededed'
)
;
background-color
:
#dfdfdf
;
}
.run:active
{
position
:
relative
;
top
:
1px
;
}
.del
{
position
:
absolute
;
font-family
:
'icomoon'
;
display
:
none
;
}
.del::after
{
border
:
5px
#d14836
solid
;
content
:
'\20'
;
border-bottom
:
10px
solid
transparent
;
border-left
:
10px
solid
transparent
;
border-right
:
10px
solid
transparent
;
font-size
:
0
;
position
:
absolute
;
left
:
20px
;
top
:
99%
;
}
.del a
{
color
:
white
;
background
:
-webkit-gradient
(
linear,
left
top,
left
bottom,
color-stop
(
0.05,
#dc4c39
)
,
color-stop
(
1,
#d14836
)
)
;
display
:
block
;
padding
:
4px
20px
;
border-radius
:
4px
;
font-size
:
1.5em
;
}
|
Javascript代码就是一个标签切换和随机显示的功能,没什么特别就不贴出来了,你会发现界面什么的实现几乎跟平常做页面没有区别,你只需要跟制作移动版页面一样实现即可,下面我们来说说如何把它放到webview上显示出来。
使用webview加载页面
webview相当于一个浏览器,为了要在webview上显示我们制作的页面,我们需要将页面相关资源作为附件放在项目的assets文件夹下,在App初始化的时候加载到webview中展示,你可以像平常组织web文件结构一样组织你的App页面,assets相当于web App的根目录,html页面中引用的资源都相对于html页面路径。
Java调用代码如下:
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
|
package
com
.
hiwanz
.
what2eat
;
import
android
.
app
.
Activity
;
import
android
.
os
.
Bundle
;
import
android
.
view
.
View
;
import
android
.
webkit
.
WebView
;
import
android
.
widget
.
Toast
;
public
class
what2eatActivity
extends
Activity
{
/**
* Called when the activity is first created.
*/
private
static
final
String
URL
=
"file:///android_asset/app.html"
;
@
Override
public
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
)
;
setContentView
(
R
.
layout
.
main
)
;
final
WebView
wvMain
=
(
WebView
)
findViewById
(
R
.
id
.
webViewMain
)
;
//取消webview长按选择文本
wvMain
.
setOnLongClickListener
(
new
WebView
.
OnLongClickListener
(
)
{
@
Override
public
boolean
onLongClick
(
View
v
)
{
return
true
;
}
}
)
;
//加载webapp
wvMain
.
loadUrl
(
URL
)
;
}
}
|
代码很简单,在App打开的时候webview加载“file:///android_asset/”路径下的app.html并取消默认长按选择文本的事件(“file:///android_asset/”路径是一个虚拟路径,用来访问Android项目中的assets目录),就这样App就可以运行起来了,看到的效果就如一开始截图的那样。
这个应用中几个关键点:
1,对于web开发人员,你只需设置应该webview控件,剩下所有功能都可以用你已有的web制作能力实现一个应用;
2,你可以使用CSS3的自定义字体来实现小图标,制作按钮而无需使用图片;
3,取消webview默认事件而不至于出现不需要的效果;
4,如果你需要快速响应你的点击效果,在javascript里绑定touch事件而不是click,因为click会有大概300ms延迟;
5,你可以通过webview的addJavascriptInterface添加js接口调用java里的函数从而实现用js控制Android系统;
6,webview.loadUrl也可以加载线上页面,可以在java代码中使用webview.loadUrl(‘javascript:alert(1)’)调用页面上的js函数,缺点就是如果当前是打开键盘的状态,执行后虚拟键盘会“关闭”;
通过简单的介绍和实践,相信你也可以通过web开发知识做出自己的App来,比如最近很火的打飞机,你可以用canvas画出来的说,而不需要用phonegap,不需要太多java代码知识,但是,懂得编写原生应用可以实现更酷的效果Y(^_^)Y,比如你也可以做个摇一摇找吃的等等(除了吃暂时没有别的想法了啊→_→)。
更多参考
WebView:https://developer.android.com/reference/android/webkit/WebView.html
手机摇一摇类:https://gist.github.com/hiwanz/6061986
Creating Fast Buttons for Mobile Web Applications:
https://developers.google.com/mobile/articles/fast_buttons?hl=zh-CN
类似文章
- 2014年08月10日 动态隐藏安卓应用图标 (2)
- 2013年07月7日 Hello Android! (2)
- 2010年07月1日 html5离线存储入门 (88)
- 2009年12月10日 IE下,写innerHTML出现未知的运行时错误 (3)
- 2012年09月6日 IE6下swfobject插flash时base标签问题 (2)