原文来自 http://caotian.appspot.com/2011/02/18/mtfy-android-demo.html  感谢作者的分享!

Android手机终于入手了,HTC Desire G7 水货2700的价格也不算太贵,终于可以开始我的Android开发之旅了,没有真机只有模拟器我还真有点底气不足。

近来给麦田福音网规划移动平台,制作了一个麦田福音网部分功能的移动程序。演示程序只做展示,不提供登陆交互,因此还是比较简单的,打算做一个类似浏览器的外壳,提供几个按钮可以切换不同的功能,再做一个导航工具栏就可以了。当然,这之前先把3G版本的网页做出来,添加了一个m.php,使用mod参数控制调用不同的功能,这个不在本文讨论范围内。

程序功能十分简单,只有一个名为MainPage的Activity。常规的,先把布局整理出来,老老实实地用Tab控件拖了四个,分别对应“麦田沙龙”,“麦田微博”,“麦田杂志”,“公共主页”,然后在每个Tab里嵌入一个WebView控件,充当浏览器功能,然后分别针对每个tab增加click事件响应函数,设定对应的WebView对加载指定的功能所需要的网页。写完后,发现这样挺傻的,WebView维护了四个,要是再添加Tab还要再增加WebView,虽然对Android刚刚入门,依然觉得不同的Tab应该可以共享一个WebView。而且Tab最好可以动态生成,这样可以在代码中控制Tab的生成,比写死到界面xml文件中要好的多。于是,打开main.xml,修改页面布局为:

<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"  android:id="@+id/TabHost01" android:layout_width="fill_parent"  android:layout_height="fill_parent">  <LinearLayout android:layout_width="fill_parent"  android:orientation="vertical" android:layout_height="fill_parent">  <TabWidget android:id="@android:id/tabs"  android:layout_width="fill_parent"  android:layout_height="wrap_content" />  <FrameLayout android:id="@android:id/tabcontent"  android:layout_width="fill_parent"  android:layout_height="fill_parent">         </FrameLayout>  </LinearLayout>  <LinearLayout android:orientation="horizontal"android:id="@+id/btnbar" android:background="#333333"android:layout_width="fill_parent" android:layout_gravity="bottom"android:layout_height="40dp"><RelativeLayout android:layout_width="50dp" android:layout_height="fill_parent"android:layout_marginLeft="10dp"><ImageView android:src="@drawable/left" android:layout_centerInParent="true"android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btnleft"/></RelativeLayout><RelativeLayout android:layout_width="50dp" android:layout_height="fill_parent"android:layout_marginLeft="10dp"><ImageView android:src="@drawable/right" android:layout_centerInParent="true"android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btnright"/></RelativeLayout><RelativeLayout android:layout_width="50dp" android:layout_height="fill_parent"android:layout_marginLeft="10dp"><ImageView android:src="@drawable/home" android:layout_centerInParent="true"android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btnhome"/></RelativeLayout>        <RelativeLayout android:layout_width="50dp" android:layout_height="fill_parent"android:layout_marginLeft="10dp"><ImageView android:src="@drawable/refresh" android:layout_centerInParent="true"android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btnrefresh"/></RelativeLayout>    <RelativeLayout android:layout_width="50dp" android:layout_height="fill_parent"android:layout_marginLeft="10dp"><ImageView android:src="@drawable/quit" android:layout_centerInParent="true"android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btnquit"/></RelativeLayout>                  </LinearLayout>
</TabHost>

正文是一排导航按钮图片,没有什么好说的。为简单,此处一个一个写出来,没有动态生成,也没必要。同时准备好导航图片,放到res\drawable-mdpi下。

下面简单说说演示程序的几点需要编程的地方:

1)       Tab的动态生成:这个毫无疑问,使用工厂生成就是了。新建一个TabFactory类,继承自abContentFactory。Tab中应包含WebView,由于共享WebView,所以WebView采用单例模式,静态只生成一次就好了,并且给它指定一个固定的数字ID,我使用了100,以方便其它页面取得对WebView的引用。代码如下:

package org.mtfy;import android.content.Context;
import android.view.View;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.TabHost.TabContentFactory;public class TabFactory implements TabContentFactory {private Context con;private static WebView webView;static final int webview = 0x100;public TabFactory(Context c){con = c;}public View createTabContent(String tag) {if(webView==null){webView = new WebView(con);webView.setId(webview);WebSettings webSettings = webView.getSettings();   webSettings.setJavaScriptEnabled(true);//webSettings.setBuiltInZoomControls(true);webView.setWebViewClient(new WebViewClient(){@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {view.loadUrl(url);return true;}});}return webView;}}

2)       在MainPage的Activity中,定义一些常量和变量。TabHost变量用来控制生成的Tab添加到当前Activity 中。webView用来引用唯一的WebView。几个ImageView为导航图片按钮的引用, url1-4为四个Tab页面对应的主url。

 private TabHost tabHost;private WebView webView;private ImageView imageViewLeft;private ImageView imageViewRight;private ImageView imageViewHome;private ImageView imageViewRefresh;private ImageView imageViewQuit;static final int webview = 0x100;static final String url1 = "http://www.mtfy.org/m.php?mod=home";static final String url2 = "http://www.mtfy.org/m.php?mod=t";static final String url3 = "http://www.mtfy.org/m.php?mod=magazine";static final String url4 = "http://www.mtfy.org/m.php?mod=public";

3)       OnCreate函数中,增加Tab动态创建的代码,并设置第一个Tab为选中状态:

 @Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);try {tabHost = (TabHost) this.findViewById(R.id.TabHost01);tabHost.setup();tabHost.addTab(tabHost.newTabSpec("tab1").setContent(new TabFactory(this)).setIndicator("麦田沙龙"));tabHost.addTab(tabHost.newTabSpec("tab2").setContent(new TabFactory(this)).setIndicator("麦田微博"));tabHost.addTab(tabHost.newTabSpec("tab3").setContent(new TabFactory(this)).setIndicator("麦田杂志"));tabHost.addTab(tabHost.newTabSpec("tab4").setContent(new TabFactory(this)).setIndicator("公共主页"));tabHost.setCurrentTab(0);final TabWidget tabWidget = tabHost.getTabWidget();for (int i = 0; i < tabWidget.getChildCount(); i++) {tabWidget.getChildAt(i).getLayoutParams().height = 40;}} catch (Exception ex) {ex.printStackTrace();}webView = (WebView) this.findViewById(webview);webView.loadUrl(url1);OnTabChangeListener changeList = new OnTabChangeListener() {public void onTabChanged(String tabId) {if (tabId.equals("tab1")) {webView.loadUrl(url1);} else if (tabId.equals("tab2")) {webView.loadUrl(url2);} else if (tabId.equals("tab3")) {webView.loadUrl(url3);} else if (tabId.equals("tab4")) {webView.loadUrl(url4);}webView.clearHistory();}};tabHost.setOnTabChangedListener(changeList);imageViewLeft = (ImageView) this.findViewById(R.id.btnleft);imageViewLeft.setOnClickListener(new OnClickListener() {public void onClick(View v) {webView.goBack();}});imageViewRight = (ImageView) this.findViewById(R.id.btnright);imageViewRight.setOnClickListener(new OnClickListener() {public void onClick(View v) {webView.goForward();}});imageViewHome = (ImageView) this.findViewById(R.id.btnhome);imageViewHome.setOnClickListener(new OnClickListener() {public void onClick(View v) {int currId = tabHost.getCurrentTab();switch (currId) {case 0:webView.loadUrl(url1);break;case 1:webView.loadUrl(url2);break;case 2:webView.loadUrl(url3);break;case 3:webView.loadUrl(url4);break;}}});imageViewRefresh = (ImageView) this.findViewById(R.id.btnrefresh);imageViewRefresh.setOnClickListener(new OnClickListener() {public void onClick(View v) {webView.reload();}});imageViewQuit = (ImageView) this.findViewById(R.id.btnquit);imageViewQuit.setOnClickListener(new OnClickListener() {public void onClick(View v) {quitConfirm();}});}

4)       取得WebView的引用,并默认加载第一个地址,即第一个Tab对应的网址。

webView = (WebView) this.findViewById(webview);
webView.loadUrl(url1);

5)       增加Tab的TabChangeListener事件,用来响应各个Tab的点击。由于几个不同的Tab共享同一个WebView,因此切换Tab的时候,同时清除WebView的缓存,防止点击后退的时候,后退到非当前Tab下的页面。

OnTabChangeListener changeList = new OnTabChangeListener() {public void onTabChanged(String tabId) {if (tabId.equals("tab1")) {webView.loadUrl(url1);} else if (tabId.equals("tab2")) {webView.loadUrl(url2);} else if (tabId.equals("tab3")) {webView.loadUrl(url3);} else if (tabId.equals("tab4")) {webView.loadUrl(url4);}webView.clearHistory();}};tabHost.setOnTabChangedListener(changeList);

6)       增加几个导航图片按钮的点击事件,分别用来后退,前进,主页,刷新,退出。点击主页的时候,先取得当前Tab,再判断需要加载哪个url。退出按钮调用了退出确认函数quitConfirm,用来询问用户是否要调用,函数内容比较简单,只是显示一个对话框,用户点确认就退出系统,否则不做处理返回。

imageViewLeft = (ImageView) this.findViewById(R.id.btnleft);imageViewLeft.setOnClickListener(new OnClickListener() {public void onClick(View v) {webView.goBack();}});imageViewRight = (ImageView) this.findViewById(R.id.btnright);imageViewRight.setOnClickListener(new OnClickListener() {public void onClick(View v) {webView.goForward();}});imageViewHome = (ImageView) this.findViewById(R.id.btnhome);imageViewHome.setOnClickListener(new OnClickListener() {public void onClick(View v) {int currId = tabHost.getCurrentTab();switch (currId) {case 0:webView.loadUrl(url1);break;case 1:webView.loadUrl(url2);break;case 2:webView.loadUrl(url3);break;case 3:webView.loadUrl(url4);break;}}});imageViewRefresh = (ImageView) this.findViewById(R.id.btnrefresh);imageViewRefresh.setOnClickListener(new OnClickListener() {public void onClick(View v) {webView.reload();}});imageViewQuit = (ImageView) this.findViewById(R.id.btnquit);imageViewQuit.setOnClickListener(new OnClickListener() {public void onClick(View v) {quitConfirm();}});
protected void quitConfirm() {AlertDialog.Builder builder = new Builder(MainPage.this);builder.setMessage("确定要退出麦田福音吗?");builder.setTitle("麦田福音提示");builder.setPositiveButton("确认",new android.content.DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int which) {dialog.dismiss();System.exit(0);}});builder.setNegativeButton("取消",new android.content.DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int which) {dialog.dismiss();}});builder.create().show();}

7)       由于手机上的返回键,默认会直接关闭Activity,因为还要检测返回键,如果按下了,再判断WebView是否有历史记录,如果有就后退,没有就提示是否退出系统,我见主流的软件都是这样做,我也不多想,仿冒一个就是了。

 @Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {if (webView.canGoBack()) {webView.goBack();} else {quitConfirm();}return false;}return false;}

至此,程序完毕,在仿真器中打开看一下 ,效果还不错:

打包成apk文件,部署到手机中:

该演示程序比较简单,本文只流水记录一下开发步骤,至此Android开发大体有了点点的了解。

Android开发之麦田福音网移动版本演示程序相关推荐

  1. Android开发学习总结(一)——搭建最新版本的Android开发环境

    最近由于工作中要负责开发一款Android的App,之前都是做JavaWeb的开发,Android开发虽然有所了解,但是一直没有搭建开发环 境去学习,Android的更新速度比较快了,Android1 ...

  2. 【Android开发】apktool官网及最新版本

    总是在网上找不到最新版本的apktool,干脆就去官网下载吧~~ 这里是apktool官网地址:https://ibotpeaches.github.io/Apktool/ 目前最新版本是v2.0.0 ...

  3. android开发关掉发现更新的官方版本,XUpdate:轻量级、高可用性的 Android 版本更新框架...

    一个轻量级.高可用性的Android版本更新框架 关于我 特点 支持post和get两种版本检查方式,支持自定义网络请求. 支持设置只在wifi下进行版本更新. 支持静默下载.自动版本更新. 提供界面 ...

  4. Android开发:集成dropbox网盘功能

    我现在要记一下,我的DropBox创建应用来下载和上传手机本地的文件和图片 1,打开dropbox 官网 https://www.dropbox.com/developers,选择 my apps,然 ...

  5. go语言1.4版本将支持面向android开发,[翻译]Go语言1.4版本将支持面向Android开发

    Go语言将支持Android 概述 我们建议将Go语言引入Android平台,重点是用Go语言编写游戏程序,API将在Android NDK中定义. 背景 Android平台被设定为一个多应用操作系统 ...

  6. 【Android 应用开发】Android 开发环境下载地址 -- 百度网盘 adt-bundle android-studio sdk adt 下载

    . 最新下载 : 2017年 8 月 28 日 : 平台 Android Studio 软件包 大小 SHA-1 校验和 Windows (64 位) android-studio-bundle-16 ...

  7. 【转载】 Android 开发环境下载地址 -- 百度网盘 adt-bundle android-studio sdk adt 下载

    本文转自http://blog.csdn.net/shulianghan/article/details/38023959 Android Studio 最详细开发环境下载 (特别推荐) : http ...

  8. Android 开发环境下载地址 -- 百度网盘 adt-bundle android-studio sdk adt 下载

    http://blog.csdn.net/shulianghan/article/details/38023959 Android 开发环境介绍 : 目前 Android 有两种开发环境, 一种是传统 ...

  9. Android开发规范:APP版本发布(全量发布、灰度发布)

    我的新书<Android App开发入门与实战>已于2020年8月由人民邮电出版社出版,欢迎购买.点击进入详情 文章目录 全量发布 灰度发布 欢迎加入Android开发交流QQ群: app ...

  10. 搭建最新版本的Android开发环境

    只为成功找方法,不为失败找借口! Android开发学习总结(一)--搭建最新版本的Android开发环境 最近由于工作中要负责开发一款Android的App,之前都是做JavaWeb的开发,Andr ...

最新文章

  1. PS怎么将自己的形状存储为自定形状?
  2. 谈行业数字化转型,先要搞明白ICT生态的共赢共生
  3. C#的textBox输入法是全角输入的问题解决
  4. Mongodb 与 Redis 调教
  5. SAP UI5 应用开发教程之四十一 - Chrome 扩展 UI5 Inspector 的离线安装和使用方法
  6. ES group分组聚合的坑
  7. mysql下载for linux 64_mysql官网下载linux版本安装包
  8. case when..then
  9. php 可逆加密方法
  10. 详细安装 kali 教程
  11. 百度热力图和高德热力图对比
  12. Node.js meitulu图片批量下载爬虫1.01版
  13. IDEA默认KeyMap映射快捷键
  14. 浅谈快速沃尔什变换(FWT)快速莫比乌斯变换(FMT)
  15. Java培训哪个机构比较好?怎么选?
  16. 内存管理之:页和页框地址变换结构
  17. 计算机怎么设置网络,电脑怎么设置网络
  18. 《一键下单:杰夫·贝佐斯与亚马逊的崛起》—— 读后总结
  19. 人体时钟android,来自独立开发者作品的冷高轮时间数字时钟app《小人人体形状造型数字手势数字麻将数字扑克数字》时钟...
  20. 加州大学伯克利分校计算机科学专业,加州大学伯克利分校研究生计算机专业排名及申请...

热门文章

  1. 上架Google Play Store,国内这些SDK千万不能用,小心被拒!
  2. 一道被前端忽略的基础题,不信看你会几题
  3. 计算机u盘 硬盘无法读取,U盘在电脑上读取不出来怎么办?
  4. 微信公众平台开发之微信红包的实现
  5. 儿童手工制作日历_变废为宝的手工日历小台历制作教程
  6. C语言中文网 读后感
  7. count在python中是什么意思_python count返回什么
  8. count时结果 hive_关于hive中的count的用法(一)
  9. python获取别人的微信好友_python使用itchat获取微信好友列表
  10. tapd怎么注册_腾讯出品的研发协作工具TAPD,可免费使用, 体验良好