动手写Android App之webview

动手写Android App之webview

看过前一篇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

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *