Code our life 日日行,不怕千万里;时时学,不怕千万卷

1九/100

Android Webview example-part 1

【翻译】Android WebView 实例(一)

原文:http://www.androidpeople.com/android-webview-example-part-1/

Webview主要用于在我们的程序中加载一段html内容。我们将分几个部分来讨论。在第一部分我们在程序中使用webview来加载一个普通的网页。LoadUrl是把网页加载到webview控件中的主要方法,所以我们使用下面的代码片段来加载一个网页

1
2
3
4
5
6
7
8
9
10
11
12
// WebViewExample.java
public class WebViewExample extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        WebView webView = (WebView) findViewById(R.id.webview);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.loadUrl("http://www.androidpeople.com");
        webView.setWebViewClient(new HelloWebViewClient());
    }
}

可是使用上面的方法,在程序中点击网页链接的时候,会使用android系统默认的浏览器来打开。为了解决这个问题,我们可以使用 shouldOverrideUrlLoading()方法和它的两个参数:webview和url。现在就可以在程序中打开网页链接了。

1
2
3
4
5
6
7
8
9
10
/**
 * 通过实现一个轻便的WebViewClient,就可以实现在程序中打开网络链接而不使用系统自带的浏览器
 */
public class HelloWebViewClient extends WebViewClient {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        view.loadUrl(url);
        return true;
    }
}
19八/100

Navigation like Themify Page

仿Themify首页的导航效果

无意中了解到Themify这个网站,看到首页的导航效果挺漂亮(实话说,主要是图片够漂亮),就仿造了一个。
点击查看demo

PS:这个demo没有什么技术含量,纯属做个记录。图片和css基本上是直接从Themify中copy过来的,js效果是自己实现,核心代码如下:

// 代码不多,加上没有什么技术含量,不做注释
var $contents = $('#slider .slides');
var $navs = $('#slider .slider-nav li');
$navs.click(function(){
    var $this = $(this);
    $this.siblings().find('a').attr('class', '');
    $('a', this)[0].className = 'activeSlide';
    var index = $navs.index($this);
    var $content = $contents.find('li').eq(index);
    $content.fadeIn();
    $content.siblings().fadeOut();
    return false;
});
17八/100

Set the environment path of linux

环境变量配置文件

在Ubuntu中有如下几个文件可以设置环境变量

  • 1、/etc/profile:在登录时,操作系统定制用户环境时使用的第一个文件,此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行。
  • 2、/etc/environment:在登录时操作系统使用的第二个文件,系统在读取你自己的profile前,设置环境文件的环境变量。
  • 3、~/.bash_profile:在登录时用到的第三个文件是.profile文件,每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该 文件仅仅执行一次!默认情况下,他设置一些环境变游戏量,执行用户的.bashrc文件。/etc/bashrc:为每一个运行bash shell的用户执行此文件.当bash shell被打开时,该文件被读取.
  • 4、~/.bashrc:该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该该文件被读取。

以上文字来自:http://blog.csdn.net/xiaosu_521/archive/2008/03/09/2160458.aspx

比如要设置java jdk的环境变量:
JAVA_HOME=/usr/java/jdk1.6.0_21 #指定JAVA_HOME所指向的目录,即java jdk所在的目录
PATH=$JAVA_HOME/bin:$PATH #将JAVA_HOME添加到PATH环境变量中
CLASSPATH=.:$JAVA_HOME/lib #设置CLASSPATH所指向的目录
export JAVA_HOME PATH CLASSPATH

添加变量之后使用命令更新:
source /etc/profile

14八/100

Life Circle of Android Activity

从Hello Android 书中截来的图。比较完整的Activity生命周期.

12八/100

AsyncTask in Android

在Android中使用AsyncTask

android中有两种实现异步的途径,AsyncTask和线程。本篇日志记录AsyncTask的使用。
实现AsyncTask基本结构如下:

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
 	private class YourTask extends AsyncTask<Object, String, Boolean> {
 
		/**
		 * callback onPreExecute()
		 * 执行 AsyncTask 前的逻辑
		 * 在UI线程中
		 */
		@Override
		protected void onPreExecute() {
			// TODO Auto-generated method stub
			super.onPreExecute();
		}
 
		/**
		 *  callback doInBackground()
		 *  真正需要实现的后台逻辑
		 */
		@Override
		protected Boolean doInBackground(Object... params) {
			// params参数与在UI线程中调用 execute时的参数对应
			return null;
		}
 
		/**
		 *  callback onProgressUpdate()
		 *  调用publishProgreess()时运行
		 *  用于接收信息
		 *  在UI线程中
		 */
		@Override
		protected void onProgressUpdate(String... values) {
			// TODO Auto-generated method stub
			super.onProgressUpdate(values);
		}
 
		/**
		 *  callback onPostExecute()
		 *  在UI线程中
		 */
		@Override
		protected void onPostExecute(Boolean result) {
			// TODO Auto-generated method stub
			super.onPostExecute(result);
		}
 
	}

执行任务,当执行AsyncTask的execute方法后,会调用AsyncTask对应的各个回调函数:

1
2
3
YourTask task = new YourTask();
// 向AsyncTask传递参数
task.execute(/* 任意数量、类型的参数*/);

补充记录

1. 在程序的title bar 中显示进度条:

1
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);

必须在setContentView之前调用。

2. 在UI线程中获取AsyncTask的状态:

task.getStatus() != AsyncTask.Status.FINISHED //如果没有完成
task.cancel(true); // 停止该任务

11八/100

Accessing Network Services in Android

在Android中访问网络

添加程序访问网络的权限

为了能够使程序访问网络资源,通常来说要设置以下权限:

  • android.permission.INTERNET
  • android.permission.ACCESS_NETWORK_STATE

检测/改变网络状态

在android中想要获得设备的网络状态,你必须要设置以下权限:

  • android.permission.ACCESS_NETWORK_STATE

改变网络状态,你必须要设置以下权限:

  • android.permission.CHANGE_NETWORK_STATE

我们可以通过 ConnectivityManager 来获取网络状态的相关信息,ConnectivityManager的getNetworkInfo方法返回一个NetworkInfo对象,有了这个对象我们就可以得到网络的相关信息,代码如下:

// 获取ConnectivityManager
ConnectivityManager connectMgr = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
// 获取NetworkInfo
NetworkInfo netInfo = conMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
// 网络是否可用
boolean isMobileAvail = netInfo.isAvailable();
// 网络是否已经处于链接状态
boolean isMobileConn = netInfo.isConnected();
// 是否处于漫游状态
boolean isRoamingConn = netInfo.isRoaming();

访问网络

一般移动设备与网络交互使用的数据是使用xml,下面举例如何获取网络中的xml数据,使用XmlPullParser和XmlResourcesParser的使用方法基本上是一样的,初始化步骤如下:

URL xmlUrl = new URL(xmlSource);
XmlPullParser parser= XmlPullParserFactory.newInstance().newPullParser();
parser.setInput(xmlUrl.openStream(), null);
9八/100

Detection of iPad & iPhone & iPod

下一个项目是做Ipad的web应用,在网上做了一些功课,记录一些开发中可能会用到东西。

使用javascript判断设备类型

    // platform的可能值为 iPad, iPod, iPhone
    alert(navigator.platform);

对应横屏竖屏引用不同的css文件

<link rel="stylesheet" media="all and (orientation:portrait)" href="portrait.css"><!-- 竖屏 -->
<link rel="stylesheet" media="all and (orientation:landscape)" href="landscape.css"><!-- 橫屏 -->

用javascript判定当前是否横屏

    alert(window.orientation)
  • * window.orientation 为 0 表示竖屏
  • * window.orientation 为 90 表示向左横屏(相对于设备下方的操作按钮)
  • * window.orientation is -90 表示向右横屏(相对于设备下方的操作按钮)
  • * window.orientation is 180 表示向反竖屏(相对于设备下方的操作按钮)

通过JS动态判断横竖屏

当用户进行横竖屏转换的时候,可以通过onorientationchange事件监听

通过CSS截取字符串,并用...结尾

.title
{
   width:200px;
   white-space:nowrap;
   word-break:keep-all; // 目前在webkit下有效 2010.8.20
   overflow:hidden;
   text-overflow:ellipsis;
}

其它

不知道有没有强制禁止竖屏或横屏的方法,希望知道的朋友告知一声:)

3八/100

Using TabHost in Android

XML布局

基本布局如下图:

如图所示:

  • 1. 实现tab的效果必须使用TabHost控件作为tab的根节点(并不是整个布局的根节点)。
  • 2. TabHost下必须有一个id为andorid:id/tabs的TabWidget控件(用于显示各tab标签)。
  • 3. TabHost下不需还有一个id为android:id/contents的FrameLayout控件(用于装载各标签的内容)
  • 4. FrameLayout控件下必须有对应tab数量的layout控件(LinearLayout、RelativeLayout等,如图中的LinearLayout01和LinearLayout)

Activity

对应activity中onCreate的代码如下

    TabHost host = (TabHost) findViewById(R.id.TabHost01);
    host.setup(); //这句很重要,之前遗漏了这句,我异常了很久=.=
 
    TabSpec one = host.newTabSpec("one");      // 创建一个tab, 这里参数中的one是一个tag,标识作用
    one.setIndicator("顯示1");                           // 设置tab的变迁文字
    one.setContent(R.id.LinearLayout01);           // 设定标签对应的内容layout
 
    TabSpec two = host.newTabSpec("two");
    two.setIndicator("顯示2");
    two.setContent(R.id.LinearLayout02);
 
    host.addTab(one);                                    // 将one 标签加入host
    host.addTab(two);
    host.setCurrentTabByTag("two");                // 设定当前选中的标签,参数就是新建tab是的tag

注意事项

如果只定义了布局(xml)文件,activity中没有对应的代码,运行程序时会报异常的,必须有以上这些基本的tabhost处理代码方能运行

其它补充

这里只是实现tab效果的其中一个方法而已,如果你的activity整个就是一个tab布局,你可以让你的activity继承TabActivity,具体实现在这篇中不进行说明

31七/100

Using Animation in your application

PS:这个主题的日志标题居然不支持中文,懒得花时间去该,就用英文标题了

android大概有四种实现动画的方式:
1. GIF图片实现
2. Frame-by-frame (好像是通过AnimationDrawable类来实现,目前还没研究)
3. OpenGL ES (说到动画怎么能不提到OpenGL呢)
4. Tweened animation (通过xml文件配置动画效果,绑定到指定控件上,这篇日志所记录的方式)

添加动画资源

在res->anim目录下建立 anim.xml


Tweened animation xml

Tweened animation xml

这段xml代码定义了一个动画效果,alpha值从0到1,时间花费1000毫秒(即1秒)

将动画绑定到指定控件上

Animation fadeIn = AnimationUtils.loadAnimaition(R.anim.anim);
// 比如有个TextView的控件,id为 title
TextView title = (TextView)findViewById(R.id.title);
// 指定控件的动画效果
title.setAnimation(fadeIn);

这样就简单得实现动画效果与控件的绑定。

取消动画效果与控件的绑定

title.clearAnimation();

指定动画效果的事件监听

动画的生命周期有三个: start, end, repeat
示例代码如下:

title.setAnimaitionListener(new AnimationListener(){
    		public void onAnimationEnd(Animation animation) {
			Intent intent = new Intent(mainActivity.this, ToActivity.class);
			startActivity(intent);
			mainActivity.this.finish();
		}
 
		public void onAnimationRepeat(Animation animation) {
			// TODO Auto-generated method stub
 
		}
 
		public void onAnimationStart(Animation animation) {
			// TODO Auto-generated method stub
 
		}
});

利用LayoutAnimationController指定一组控件的动画效果

LayoutAnimationController controller = new LayoutAnimationController(fadeIn);
// 假设有个TableRow控件的ID为 row
TableRow row = (TableRow)findViewById(R.id.row);
row.setLayoutAnimation(controller);

通过setLayoutAnimation方法,我们就可以给TableRow下的所有元素设定同一个动画效果。有一个需要注意的地方,TableRow下的元素的效果并不是同一时间开始运行的。比如本日志的这个例子,定义动画的xml文件中,alpha节点的android:duration属性,指定整个动画效果执行所需要的时间,在这里我们设定了1000,那么,TableRow下的元素将会一个一个运行,间隔时间为android:duration的1/2(无论TableRow下有多少个空间,都是1/2),在这里就是0.5秒。比如TableRow下有两个控件,那么当第一个控件动画效果执行到0.5秒时,第二个控件才开始执行。所以,当所有控件的效果都运行完了之后,总共花时1.5秒。

其它

xml文件中的alpha节点还有一个经常会用到的属性android:startOffset,这个属性设定动画开始的时间,例如将这个属性值设为2000,动画将会在2秒之后执行。

31七/100

创建android应用程序的偏好设定

创建应用程序设定

一款应用程序通常都需要存储一些基本的状态信息和用户数据,我们可以使用Android的Shared Preferences来实现这个功能。

在一个应用程序的所有activity中,我们都可以通过一个名称来访问Shared Preferences。因为这些设定信息是整个程序公用的,所以我们可以创建一个activity的子类(在这里举例为AppActivity),让程序中所有其他的activity继承AppActivity,我们在AppActivity中声明一个成员变量,用于标记Shared Preferencess的名称,这样一来在所有的activity中我们都可以统一地访问我们的Shared Preferencess。

// 在AppActivity中声明一个成员变量
public static final String APP_PREFERENCES = “APP_PREF”;

创建Shared preferences是没有数量限制的,所以你可以使用不同命名对应不同的类别,例如你可以分为应用设定(APP_PREFERENCES)和用户设定(USER_PREFERENCES),怎么组织Shared Preferences取决于你自己。

添加Shared Preferences到应用程序中,需要以下几个步骤:
1. 使用getSharedPreferences()方法获取一个SharedPreferences的实例
2. 创建一个SharedPreferences.Editor对象
3. 使用editor对象修改设定
4. 使用editor的commit()方法提交修改

存储特定的设定

Shared Preferences中的每个设定都是以键值对的形式存储的,值可以是以下这些类型:
. Boolean
. Float
. Integer
. Long
. String

当你决定好了要存储那些设定信息之后,你需要取得一个SharedPreferences实例并且使用Editior对象更新设定并提交修改。下面的例子中,存储了两个设定(用户名和年龄):

SharedPreferences settings = 
    getSharedPreferences(APP_PREFERENCES , MODE_PRIVATE); 
SharedPreferences.Editor prefEditor = settings.edit(); 
prefEditor.putString(“UserName”, “JaneDoe”); 
prefEditor.putInt(“UserAge”, 22); 
prefEditor.commit();

我们还可以通过editor的clear()方法把设定清空,或者使用remove()方法,根据名称删除指定的设定。

获取应用的设定

获取Shared Preference的设定值比创建还要简单,你不需要editor对象。下面的示例展示了怎么样获取Shared Preference的设定:

SharedPreferences settings = 
    getSharedPreferences(APP_PREFERENCES, MODE_PRIVATE);
if (settings.contains(“UserName”) == true) { 
    // 这样就可以获取key为 UserName的值了, getString()的第二个参数是当UserName没有值的时候作为默认值
    String user = Settings.getString(“UserName”, “Default);
}

你可以使用SharedPreferences对象根据名称检测一个设定,获取一个强类型的设定或者 获取所有设定,通过使用map来存储他们。

   下一页