Android开发之麦田福音网移动版本演示程序
2011-07-14 22:33
435 查看
原文来自 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,修改页面布局为:
正文是一排导航按钮图片,没有什么好说的。为简单,此处一个一个写出来,没有动态生成,也没必要。同时准备好导航图片,放到res\drawable-mdpi下。
下面简单说说演示程序的几点需要编程的地方:
1) Tab的动态生成:这个毫无疑问,使用工厂生成就是了。新建一个TabFactory类,继承自abContentFactory。Tab中应包含WebView,由于共享WebView,所以WebView采用单例模式,静态只生成一次就好了,并且给它指定一个固定的数字ID,我使用了100,以方便其它页面取得对WebView的引用。代码如下:
2) 在MainPage的Activity中,定义一些常量和变量。TabHost变量用来控制生成的Tab添加到当前Activity 中。webView用来引用唯一的WebView。几个ImageView为导航图片按钮的引用, url1-4为四个Tab页面对应的主url。
3) OnCreate函数中,增加Tab动态创建的代码,并设置第一个Tab为选中状态:
4) 取得WebView的引用,并默认加载第一个地址,即第一个Tab对应的网址。
5) 增加Tab的TabChangeListener事件,用来响应各个Tab的点击。由于几个不同的Tab共享同一个WebView,因此切换Tab的时候,同时清除WebView的缓存,防止点击后退的时候,后退到非当前Tab下的页面。
6) 增加几个导航图片按钮的点击事件,分别用来后退,前进,主页,刷新,退出。点击主页的时候,先取得当前Tab,再判断需要加载哪个url。退出按钮调用了退出确认函数quitConfirm,用来询问用户是否要调用,函数内容比较简单,只是显示一个对话框,用户点确认就退出系统,否则不做处理返回。
7) 由于手机上的返回键,默认会直接关闭Activity,因为还要检测返回键,如果按下了,再判断WebView是否有历史记录,如果有就后退,没有就提示是否退出系统,我见主流的软件都是这样做,我也不多想,仿冒一个就是了。
至此,程序完毕,在仿真器中打开看一下 ,效果还不错:
打包成apk文件,部署到手机中:
该演示程序比较简单,本文只流水记录一下开发步骤,至此Android开发大体有了点点的了解。
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(){ @Override public 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为选中状态:
@Override public 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是否有历史记录,如果有就后退,没有就提示是否退出系统,我见主流的软件都是这样做,我也不多想,仿冒一个就是了。
@Override public 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开发大体有了点点的了解。
相关文章推荐
- [Phonegap+Sencha Touch] 移动开发26 Android下的sencha touch程序,转屏时,Ext.Viewport不能触发orientationchange事件的解决办法
- [Phonegap+Sencha Touch] 移动开发26 Android下的sencha touch程序,转屏时,Ext.Viewport不能触发orientationchange事件的解决办法
- Android模似打电话程序实现 - Android移动开发技术文章
- Android移动开发-在Android 5.0 以上版本自定义Toolbar的实现
- Rad Studio 10.1 UP1 移动开发 关于编译ANDROID版本
- 【移动安全】Android程序开发3种方式比较
- 提高到精通移动(android、IOS)App应用服务程序开发
- 我的Android笔记(一)―― hello world程序结构分析 - Android移动开发技术文章
- Android开发环境搭建全程演示(jdk+eclipse+android sdk包含版本更新)
- [Phonegap+Sencha Touch] 移动开发26 Android下的sencha touch程序,转屏时,Ext.Viewport不能触发orientationchange事件的解决的方法
- Rad Studio 10.1 UP1 移动开发 ANDROID目标版本切换
- 小程序开发文档:移动应用支持微信小程序类型分享(Android应用)
- Android程序开发之给背景图加上移动的手势
- Android开发学习笔记-实现联网检测程序版本
- 关于Google Maps API V2 android版本的开发(总结)
- 【移动开发】Android中WIFI开发总结(二)
- android 开发 程序中下载安装APK文件 问题汇总 解析程序包时出现问题
- Android开发环境搭建全程演示(jdk+eclip+android sdk)
- NUPT_移动应用开发 android简历app