Facebook Twitter LinkedIn E-mail
magnify
Home Posts tagged "Android"

Android设计–有创造性的愿景

android

从ICS开始,Anroid的设计以下面三个方面为中心,这三个原则不仅仅应用到Android系统的核心应用中,同时也应用到整个Android系统。当你开发使用Android时也要注意以下三个目标:

使我为之眩目
美丽不仅局限于表面,App应用是圆润并且在多个层次上具有美感,界面切换快而清晰。布局和文字干脆有意义。应用图标自成艺术品,就像一个构造精良的工具一样,你的应用应当集美观,简单和功用于一体,致力创造魔幻的用户体验。
简化我的生活
Android应用使生活变得简单,而且易于理解使用。但用户首次使用你的应用时,他们应该凭直觉就可以掌握应用的主要功能。然而设计不仅仅局限在第一次用户体验。Android应用应当去掉一些比如文件管理和同步方面的后续维护工作。永远不要使用繁琐的步骤来完成简单的工作,而复杂的工作应当裁剪到用户可以接受的程度。各年龄段各个文化背景的人群都不应困惑于过多的选择项和不必要的界面切换。
使我为之惊奇
仅仅使得应用变得易于使用是不够的。Android应用应当鼓励人们尝试新的事物,以全新的视角来使用你的应用。Android允许人们通过多任务,通知和共享以全新的流程来组合使用多个应用。与此同时,你的应用依然具有个性化,以简洁和优雅的方式诠释新的技术。

 

引路蜂Android技术网站开通了

之前在引路蜂技术博客我们花了大量的篇幅介绍了Android开发的相关知识,距离上次介绍Android开发已经有一年有余,这期间Android版本也有了很大的变化,好在Android的版本的基本支持向下兼容,因此以前的介绍的技术基本上还是适用的,但为了和最新的Android技术保持一致,我们准备重新开始介绍Android开发,主要介绍developer.android.com 上的知识涉及Design,Develop和distribution ,此外加上图形(主要是Opengl ES方面的知识)和游戏开发。

android

同时我们也将再次逐个分析随Android SDK发布的例子,主要是ApiDemos中的例子。

网站地址 http://www.androidapidemos.com/

20140809001

 

关于Android引路蜂地图应用源码的简单说明

前面完整的Android引路蜂地图应用源码下载 提供了源码下载,这里对这个项目做个简单的说明以方便阅读。

整个应用代码量在4000行左右,不算很大,下面是对代码中主要Package的说明:

文件名 空行 注释 代码行 说明
AboutActivity.java 13 4 47 关于软件说明
app\GNavigatorApplication.java 27 23 93 主应用类
app\SessionInfo.java 9 3 11 保持一些全局变量
app\SharedMapInstance.java 13 38 18 保存RasterMap类实例
app\SharedSearchResults.java 12 0 22 保存查询结果
database\DatabaseAssistant.java 42 63 122 用于数据库访问,用来管理设备,这部分可以不看
database\DBAdapter.java 27 126 77
database\DBMapper.java 4 38 7
database\DeviceDBMapper.java 20 86 130
database\DeviceLocationHistoryDBMapper.java 19 56 60
database\PersistentFacade.java 28 168 67
dataobject\Device.java 14 0 15 设备定义,设备命令,这部分可以不看
dataobject\DeviceCommand.java 7 0 17
dataobject\DeviceLocationHistory.java 5 0 7
device\AddDeviceActivity.java 14 1 70 软件可以用来跟踪其他设备或者报告设备当前位置,这部分可以不看
device\DeviceCommandListActivity.java 39 4 202
device\DeviceControlTabActivity.java 16 1 80
device\DeviceInfoActivity.java 8 1 49
device\DeviceLocationHistoryListActivity.java 19 1 81
device\ManageDeviceListActivity.java 44 4 208
drawing\AndroidFont.java 9 27 17 和Android平台相关的引路蜂图形接口实现
drawing\AndroidGraphics.java 20 150 57
drawing\AndroidGraphicsFactory.java 10 83 23
drawing\AndroidImage.java 20 114 65
gis\FileMapTiledZone.java 17 23 43 用来访问离线地图文件
GNavigatorActivity.java 82 31 516 主Activity
GuidebeeMapView.java 52 25 301 地图View,可以自定义并扩展,支持Gesture缩放等
location\LocationService.java 54 55 90 GPS服务
mapmode\MapModeListActivity.java 16 11 50 选项地图模式界面
routing\RouteDetailActivity.java 52 34 274 显示详细路径
routing\RoutingActivity.java 26 1 159 路径查询界面
search\SearchResultListActivity.java 41 25 246 查询结果
search\SearchSuggestionProvider.java 2 0 9 查询提示
settings\SettingsActivity.java 19 26 86 软件设置界面
sms\DeviceMessage.java 4 0 5 控制设备的短消息处理,这部分可以不看
sms\DeviceMessageCenter.java 7 0 18
sms\DeviceMessageProcessor.java 45 1 209
sms\SmsMessageReceiver.java 13 15 28
ToolbarButton.java 36 1 259 工具条自定义View

其中和Device相关的部分,包database, dataobject, device, sms 部分可以跳过不需要看,这部分和地图API使用关系不大,主要用来监视GPS设备或其它手机的位置。

drawing 包实现了地图API中和图形系统相关接口的Android平台上实现 ,引路蜂地图开发包中Gis.Drawing 类定义了几个抽象类或接口,对不同平台的图形系统进行了抽象。这些绘图的接口不同,如果在引路蜂地图开发包直接引用这些类方法,这样不同平台就会需要编译不同的开发包。通过抽象处理,引路蜂地图开发包并直接调用平台相关的图形类方法。而是通过 开发包 + 平台相关图形系统实现的方法,就可以实现跨平台.具体可以参见图形子系统

GuidebeeMapView 主要用来显示地图,这个给出的是一个参考实现,支持触摸屏平移,事件你可以把地图放在任何可以显示Image对象的控件上,添加你自己的Logo,支持MultiTouch 缩放等,本身是个自定义View (为View的子类),你可以自由扩展其功能。

FileMapTiledZone 用来支持从文件读取离线地图,这部分代码可以不需修改应用到你自己编写的引路蜂地图应用中。

应用程序框架基于RoboGuice 以简化代码,关于RoboGuice的使用可以参见本博客 的Android RoboGuice 使用指南

搜索使用Android平台的Search Framework。可以参见

App/Search/Invoke Search
App/Search/Query Search Results

再看一下项目的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.pstreets.navigator"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="4" />

    <application
        android:name=".app.GNavigatorApplication"
        android:icon="@drawable/navigator"
        android:label="@string/app_name"
        android:screenOrientation="portrait"
        android:theme="@android:style/Theme.Black.NoTitleBar" >
        <activity android:name=".GNavigatorActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <meta-data
                android:name="android.app.default_searchable"
                android:value=".search.SearchResultListActivity" />
        </activity>
        <activity
            android:name=".search.SearchResultListActivity"
            android:launchMode="singleTop" >
            <intent-filter>
                <action android:name="android.intent.action.SEARCH" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>

            <meta-data
                android:name="android.app.searchable"
                android:resource="@xml/searchable" />
        </activity>
        <activity
            android:name=".AboutActivity"
            android:launchMode="singleTop" >
        </activity>
        <activity
            android:name=".mapmode.MapModeListActivity"
            android:launchMode="singleTop" >
        </activity>
        <activity
            android:name=".routing.RoutingActivity"
            android:launchMode="singleTop" >
        </activity>
        <activity
            android:name=".routing.RouteDetailActivity"
            android:launchMode="singleTop" >
        </activity>
        <activity
            android:name=".device.ManageDeviceListActivity"
            android:launchMode="singleTop" >
        </activity>
        <activity
            android:name=".device.AddDeviceActivity"
            android:launchMode="singleTop" >
        </activity>
        <activity
            android:name=".device.DeviceControlTabActivity"
            android:launchMode="singleTop" >
        </activity>
        <activity
            android:name=".device.DeviceCommandListActivity"
            android:launchMode="singleTop" >
        </activity>
        <activity
            android:name=".device.DeviceInfoActivity"
            android:launchMode="singleTop" >
        </activity>
        <activity
            android:name=".device.DeviceLocationHistoryListActivity"
            android:launchMode="singleTop" >
        </activity>
        <activity
            android:name=".settings.SettingsActivity"
            android:launchMode="singleTop" >
        </activity>

        <receiver
            android:name=".sms.SmsMessageReceiver"
            android:enabled="true" >
            <intent-filter android:priority="1000" >
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>

        <provider
            android:name=".search.SearchSuggestionProvider"
            android:authorities="com.pstreets.navigator.search.SearchSuggestionProvider" />
    </application>

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_OWNER_DATA" />
    <uses-permission android:name="android.permission.WRITE_OWNER_DATA" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

</manifest>

使用的permission 需要有INTERNET(地图API需要访问网络) ,WRITE_EXTERNAL_STORAGE (离线地图需要访问SD卡)其它权限可以根据需要添加。
最后看一下软件的项目目录结构:

项目引用三个库,其中libgisengine.jar 为引路蜂地图API,其它两个为roboguice 库。 支持中英文两种资源 values-zh-rCN 为中文string 资源。

 

完整的Android引路蜂地图应用源码下载

这里提供一个比较完整的引路蜂地图Android应用源码下载,基本涵盖了引路蜂地图API的所有功能,包括离线地图,路径查询,地址查询,地图模式选择等。

设备上在Galaxy Nexus 和 Nexus S ,Nexus 7 Tablet 测试通过,可以做为你学习或开发引路蜂地图应用的参考。

完整的Android引路蜂地图应用源码 下载

主界面

搜索 ,包括: 地址查询, 本地查询,IP地图查询,经纬度查询

查询结果显示

路径查询

路径地图显示

地图模式:支持多种地图模式,并可以支持自定义地图

地址反编码

关于离线地图

应用缺省读取所有存放在SD卡guidebee 目录下所有 .map 文件,代码如下:

MapTileStreamReader streamReader = SharedMapInstance.mapTileDownloadManager
					.getInteralMapTileStreamReader();

	SharedMapInstance.worldMapFileStream = getResources()
			.openRawResource(R.raw.world);
	MapTiledZone worldmapZone = new MapTiledZone(new DataInputStream(
			SharedMapInstance.worldMapFileStream));
	streamReader.addZone(worldmapZone);
	try {
		File sdcardDir = Environment.getExternalStorageDirectory();
		File guidebeeDir = new File(sdcardDir, "guidebee");
		if (guidebeeDir.exists()) {
			FilenameFilter filter = new FilenameFilter() {
				public boolean accept(File dir, String filename) {
					if (filename.endsWith(".map")) {
						return true;
					}
					return false;

				}
			};

			String[] allMapfiles = guidebeeDir.list(filter);
			String path = guidebeeDir.getAbsolutePath();
			if (allMapfiles != null) {
				for (int i = 0; i < allMapfiles.length; i++) {

					FileMapTiledZone mapTileZone = new FileMapTiledZone(
							path + File.separator + allMapfiles[i],
							false);
					Log.p(allMapfiles[i]);
					streamReader.addZone(mapTileZone);
				}

			}
		}

	} catch (Exception e) {

	}finally{
		streamReader.open();
	}

} catch (Exception e) {

}

你也可以根据你自己的需求放在其它目录下,记得要更改代码中对应的路径。

GPS支持,应用也提供了GPS支持,可以显示当前位置

关于软件使用许可,源码中包含试用许可

地图上会随机显示“Guidebee” 水印。正式版去除水印,关于正式版可以参见版本说明。

离线地图下载可以参见 离线地图工具 和离线地图下载 ,你可以通过离线地图工具自己制作离线地图,或是从本网站下载。

软件采用RoboGuice ,关于RoboGuice可以参见

Android RoboGuice 使用指南

  1. Android RoboGuice 使用指南(1):概述
  2. Android RoboGuice 使用指南(2):第一个例子Hello World
  3. Android RoboGuice 使用指南(3):Bindings 概述
  4. Android RoboGuice 使用指南(4):Linked Bindings
  5. Android RoboGuice 使用指南(5):Binding Annotations
  6. Android RoboGuice 使用指南(6):Instance Bindings
  7. Android RoboGuice 使用指南(7):@Provides Methods
  8. Android RoboGuice 使用指南(8):Provider Bindings
  9. Android RoboGuice 使用指南(9):Untargetted Bindings
  10. Android RoboGuice 使用指南(10):Just-in-time Bindings
  11. Android RoboGuice 使用指南(11):Scopes
  12. Android RoboGuice 使用指南(12):如何绑定generic类型
  13. Android RoboGuice 使用指南(13):RoboGuice 功能描述
  14. Android RoboGuice 使用指南(14):Inject View
  15. Android RoboGuice 使用指南(15):Inject Context
  16. Android RoboGuice 使用指南(16):Standard Injection
  17. Android RoboGuice 使用指南(17):Inject Extra
  18. Android RoboGuice 使用指南(18):Inject Resources
  19. Android RoboGuice 使用指南(19):发送接收Events
  20. Android RoboGuice2 使用指南(1): 概述
  21. Android RoboGuice2 使用指南(2): 第一个例子Hello World
  22. Android RoboGuice2 使用指南(3): Inject 自定义View
  23. Android RoboGuice2 使用指南(4): 综合示例Astroboy

完整的Android引路蜂地图应用源码 下载

 

Android RoboGuice2 使用指南(4): 综合示例Astroboy

前面介绍了RogoGuice2.0的基本用法,其它使用可以参见RoboGuice1.1开发指南,2.0中提供了对Fragment,View(自定义View中使用注入)的支持,本博客不再一一介绍。

本例使用的是RoboGuice 开发包中的简单示例Astroboy(阿童木)。涉及的使用RoboGuice2.0 的一些常用方法。

本例下载(Eclipse项目)。

下面对项目中RoboGuice2的使用进行解释。因为本例没使用自定义绑定,所以无需使用res/values/roboguice.xml 定义Module. 如有自定义模块,可以参见Android RoboGuice2 使用指南(2): 第一个例子Hello World

1. 类Astroboy

// There's only one Astroboy, so make it a @Singleton.
// This means that there will be only one instance of Astroboy in the entire
// app.
// Any class that requires an instance of Astroboy will get the same instance.
// This also means this class needs to be thread safe, of course
@Singleton
public class Astroboy {

	// Because Astroboy is a Singleton, we can't directly inject the current
	// Context since the current context may change depending on what activity
	// is using Astroboy
	// at the time. Instead we use the application context.
	// Vibrator is bound to context.getSystemService(VIBRATOR_SERVICE) in
	// DefaultRoboModule.
	// Random has no special bindings, so Guice will create a new instance for
	// us.
	@Inject	Application application;
	@Inject	Vibrator vibrator;
	@Inject	Random random;

	public void say(String something) {
		// Make a Toast, using the current context as returned by the Context
		// Provider
		Toast.makeText(application, "Astroboy says, \"" + something + "\"",
				Toast.LENGTH_LONG).show();
	}

	public void brushTeeth() {
		vibrator.vibrate(
				new long[] { 0, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50,
						200, 50, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, },
				-1);
	}

	public String punch() {
		final String expletives[] = new String[] { "POW!", "BANG!", "KERPOW!",
				"OOF!" };
		return expletives[random.nextInt(expletives.length)];
	}
}

程序中只希望使用一个Astroboy实例,因此可以使用@Singleton标注,此后任何使用

@Inject Astroboy astroboy;

注入的Astroboy都会指向同一个实例,这也是符合Singleton设计模式的。

@Inject Application application; 注入Application实例。参见Android RoboGuice 使用指南(15):Inject Context

@Inject Vibrator vibrator; 注入Android Vibrator实例,参见Android RoboGuice 使用指南(16):Standard Injection

@Inject Random random; 对于普通的Java 类型(POJO),如果该类具有缺省构造函数(不带参数的等),也可以使用RoboGuice自动注入实例。

因此当Astroboy创建时,RoboGuice 自动为application, vibrator, random 创建实例,无需使用new 或参数传入来构造它们。

2. 类AstroboyRemoteControl

/**
 * A class to control Astroboy remotely.
 *
 * This class uses the current context, so we must make it @ContextSingleton.
 * This means that there will be one AstroboyRemoteControl for every activity or
 * service that requires one. Note that we actually ask for the Activity, rather
 * than the Context (which is the same thing), because we need access to some
 * activity-related methods and this saves us from having to downcast to an
 * Activity manually.
 *
 * It also asks RoboGuice to inject the Astroboy instance so we can control him.
 *
 * What you'll learn in this class - What @ContextScope means and when to use it
 * - How to inject an Activity instead of a Context (which is really the same
 * thing) - How to use RoboGuice's convenient and flexible logging facility, Ln.
 */
@ContextSingleton
public class AstroboyRemoteControl {

	// The Astroboy class has been decorated with @Singleton, so this instance
	// of Astroboy will be the same instance used elsewhere in our app.
	// Injecting an Activity is basically equivalent to "@Inject Context context",
	// and thus also requires @ContextScope. If you wanted, you could also
	// @Inject Application, Service, etc. wherever appropriate.
	@Inject	Astroboy astroboy;
	@Inject	Activity activity;

	public void brushTeeth() {
		// More info about logging available here:
		// http://code.google.com/p/roboguice/wiki/Logging
		Ln.d("Sent brushTeeth command to Astroboy");
		astroboy.brushTeeth();
	}

	public void say(String something) {
		Ln.d("Sent say(%s) command to Astroboy", something);
		astroboy.say(something);
	}

	public void selfDestruct() {
		Toast.makeText(
				activity,
				"Your evil remote control has exploded! Now Astroboy is FREEEEEEEEEE!",
				Toast.LENGTH_LONG).show();
		activity.finish();
	}
}

与Singleton类似的一个Scope标注为@ContextSingleton ,它表示对于每个Activity实例有一个实例,不同的activity对应不同的实例。

@Inject Astroboy astroboy; 注入同一个Astroboy实例(Singleton)。

@Inject Astroboy astroboy; 注入对应的Activity实例。

3. 类AstroboyMasterConsole

/**
 * This activity uses an AstroboyRemoteControl to control Astroboy remotely!
 *
 * What you'll learn in this class: - How to use @InjectView as a typesafe
 * version of findViewById() - How to inject plain old java objects as well
 * (POJOs) - When injection happens - Some basics about injection, including
 * when injection results in a call to an object's default constructor, versus
 * when it does something "special" like call getSystemService()
 */
@ContentView(R.layout.main)
public class AstroboyMasterConsole extends RoboActivity {

	// Various views that we inject into the activity.
	// Equivalent to calling findViewById() in your onCreate(), except more
	// succinct
	@InjectView(R.id.self_destruct)	Button selfDestructButton;
	@InjectView(R.id.say_text)	EditText sayText;
	@InjectView(R.id.brush_teeth)	Button brushTeethButton;
	@InjectView(tag = "fightevil")	Button fightEvilButton; // we can also use tags if we want

	// Standard Guice injection of Plain Old Java Objects (POJOs)
	// Guice will find or create the appropriate instance of AstroboyRemoteControl for us
	// Since we haven't specified a special binding for AstroboyRemoteControl,
	// Guice will create a new instance for us using AstroboyRemoteControl's default constructor.
	// Contrast this with Vibrator, which is an Android service that is
	// pre-bound by RoboGuice.
	// Injecting a Vibrator will return a new instance of a Vibrator obtained by
	// calling
	// context.getSystemService(VIBRATOR_SERVICE). This is configured in
	// DefaultRoboModule, which is
	// used by default to configure every RoboGuice injector.
	@Inject	AstroboyRemoteControl remoteControl;
	@Inject	Vibrator vibrator;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState); // @Inject, @InjectResource, and
											// @InjectExtra injection happens
											// during super.onCreate()

		sayText.setOnEditorActionListener(new OnEditorActionListener() {
			public boolean onEditorAction(TextView textView, int i,
					KeyEvent keyEvent) {

				// Have the remoteControl tell Astroboy to say something
				remoteControl.say(textView.getText().toString());
				textView.setText(null);
				return true;
			}
		});

		brushTeethButton.setOnClickListener(new OnClickListener() {
			public void onClick(View view) {
				remoteControl.brushTeeth();
			}
		});

		selfDestructButton.setOnClickListener(new OnClickListener() {
			public void onClick(View view) {

				// Self destruct the remoteControl
				vibrator.vibrate(2000);
				remoteControl.selfDestruct();
			}
		});

		// Fighting the forces of evil deserves its own activity
		fightEvilButton.setOnClickListener(new OnClickListener() {
			public void onClick(View view) {
				startActivity(new Intent(AstroboyMasterConsole.this,
						FightForcesOfEvilActivity.class));
			}
		});

	}

}

AstroboyMasterConsole 为主Activity,要使用RoboGuice,则Activity需从RoboActivity派生,其它如Service,Fragment等可以参见Android RoboGuice 使用指南(13):RoboGuice 功能描述

@InjectView(R.id.self_destruct) Button selfDestructButton;  注入View实例,功能同findViewById。 它的另外一种方法是使用Tag,如

@InjectView(tag = “fightevil”) Button fightEvilButton ,功能一样。

这个类使用@ContentView(R.layout.main) 为Activity指明ContentView,无需再调用setContentView.

4. 类FightForcesOfEvilActivity

/**
 * Things you'll learn in this class: - How to inject Resources - How to use
 * RoboAsyncTask to do background tasks with injection - What it means to be a @Singleton
 */
public class FightForcesOfEvilActivity extends RoboActivity {

	@InjectView(R.id.expletive)	TextView expletiveText;

	// You can also inject resources such as Strings, Drawables, and Animations
	@InjectResource(R.anim.expletive_animation)	Animation expletiveAnimation;

	// AstroboyRemoteControl is annotated as @ContextSingleton, so the instance
	// we get in FightForcesOfEvilActivity will be a different instance than
	// the one we got in AstroboyMasterConsole
	// @Inject AstroboyRemoteControl remoteControl;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.fight_evil);

		expletiveText.setAnimation(expletiveAnimation);
		expletiveAnimation.start();

		// Throw some punches
		for (int i = 0; i < 10; ++i)
			new AsyncPunch(this) {
				@Override
				protected void onSuccess(String expletive) throws Exception {
					expletiveText.setText(expletive);
				}

				// We could also override onException() and onFinally() if we
				// wanted

			}.execute();

	}

	// This class will call Astroboy.punch() in the background
	public static class AsyncPunch extends RoboAsyncTask<String> {

		// Because Astroboy is a @Singleton, this will be the same
		// instance that we inject elsewhere in our app.
		// Random of course will be a new instance of java.util.Random, since
		// we haven't specified any special binding instructions anywhere
		@Inject	Astroboy astroboy;
		@Inject	Random random;

		public AsyncPunch(Context context) {
			super(context);
		}

		public String call() throws Exception {
			Thread.sleep(random.nextInt(5 * 1000));
			return astroboy.punch();
		}
	}
}

@InjectResource(R.anim.expletive_animation) Animation expletiveAnimation; 注入资源,可以参见Android RoboGuice 使用指南(18):Inject Resources

从代码中可以看出使用RoboGuice 注入可以简化程序,运行结果如下图:

 

Android RoboGuice2 使用指南(3): Inject 自定义View

前面介绍了Android RoboGuice2 的HelloWorld示例,并介绍了从RoboGuice 1.1 升级到RoboGuice2.0 的主要注意事项。其它的基本概念和RoboGuice1.1基本一样,可以参见

本例介绍如何Inject自定义的View,Inject自定义的View和Android自带的View(如TextView,Button)方法一样。

本例使用一个自定义的TextView,每隔1秒显示当前时间。前定义如下:

//--------------------------------- PACKAGE ------------------------------------
package com.pstreets.guice.customview;

//--------------------------------- IMPORTS ------------------------------------
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.widget.TextView;

import java.util.Calendar;
import java.util.Date;

public final class TimeTextView extends TextView {

	public TimeTextView(Context context, AttributeSet attrs) {
		super(context, attrs);
		postDelayed(mUpdateView, mRepeatTimePeriod);

	}

	private void setTimeString() {
		Calendar c = Calendar.getInstance();
		Date currentTime = c.getTime();
		String timeString = formatTime(currentTime);
		setText(timeString);
	}

	private Handler mHandler = new Handler();
	/**
	 * one second.
	 */
	private int mRepeatTimePeriod = 1000;

	private Runnable mUpdateView = new Runnable() {

		@Override
		public void run() {
			TimeTextView.this.setTimeString();
			// Force toggle again in a second
			mHandler.postDelayed(this, mRepeatTimePeriod);
		}

	};

	private String formatTime(Date time) {
		int hours = time.getHours();
		int miniutes = time.getMinutes();
		int seconds = time.getSeconds();
		String ret = "";
		if (hours < 10) {
			ret += "0";
		}
		ret += hours + ":";
		if (miniutes < 10) {
			ret += "0";
		}
		ret += miniutes + ":";
		if (seconds < 10) {
			ret += "0";
		}
		ret += seconds;

		return ret;
	}

}

修改main.xml

<?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"
    >
<TextView
    android:id="@+id/hello"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello"
    />
<TextView

    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:layout_weight="1.0"

    />
<com.pstreets.guice.customview.TimeTextView
    android:id="@+id/txtTime"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"

    />
</LinearLayout>

定义该TimeTextView的id为txtTime。

这样可以在对应的Activity中使用InjectView 来给对应的txtTime 自动赋值(注入)。

 

@ContentView(R.layout.main)
public class GuiceDemo extends RoboActivity  {

	@InjectView (R.id.txtTime) TimeTextView txtTime;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        txtTime.setTextColor(0xFFFF0000);

    }

}

由于GuiceDemo是从RoboActivity派生的,在onCreate 第一行的super.onCreate() 完成注入功能。如果你对RoboGuice1.1 熟悉的话,在使用注入的变量前如txtTime,需要执行setContentView。
在RoboGuice2.0中你可以使用同样的方法,2.0还提供了一个简单的标注方法@ContentView ,如本例,为Activity设置ContentView。

本例下载 

从本例可以看出,和RoboGuice1.1 相比,RoboGuice2.0在使用上要简洁的多。本例只需从RoboActivity派生,不在需要定义Application等。