看过前一篇hello world类的Android开发入门文章《Hello Android!》,也许你一点成就感都没有,那么接下来我来分享我后续学习的过程,使用webview内嵌HTML、CSS和JS做一个简单的App。
先睹为快,如图,我们需要做一个随机选餐厅的应用,它有三个tab可以切换,一个选餐厅面板,一个添加餐厅面板,一个关于面板:
虽然很简陋,但是看起来像那么一回事,所有的界面都是用HTML和CSS实现的,JS实现标签切换和随机选餐厅功能,正如你做普通的页面一样,你要做的只是把页面放到Android的webview里。
编写App界面
按照之前文章里的步骤,我们只需添加一个webview控件,把它设置为填充父级和隐藏标题栏,也就是说除了状态栏,它已经是“全屏”的了,布局代码如下:
布局文件main.xml代码
XHTML
<?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设置为无标题栏
XHTML
<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结构:
XHTML
<!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> |
样式编写:
CSS
/*html5doctor.com Reset Stylesheet v1.6.1Last Updated: 2010-09-17Author: 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调用代码如下:
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