android wear开发之绘制表盘.doc_第1页
android wear开发之绘制表盘.doc_第2页
android wear开发之绘制表盘.doc_第3页
android wear开发之绘制表盘.doc_第4页
android wear开发之绘制表盘.doc_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

当你配置完工程并且添加了实现表盘service的类后,你可以开始初始化并绘制表盘。Android SDK中包含表盘示例,示例位置在android-sdk/samples/android-21/wearable/WatchFace目录下。service很多方面的实现描述都在这里面,例如初始化和检测设备功能,可以应用于任何表盘,所以你可以在你的表盘中复用这些代码。初始化你的表盘当系统加载你的service,你应该分配和初始化大部分表盘所需的资源,包括加载bitmap资源,创建定时器对象来运行自定义动画,配置paint对象和风格,以及执行其他计算。你可以只执行一次这些操作并且复用他们的执行结果。这样可以提高表盘的性能。初始化表盘有以下几步:1. 声明自定义定时器变量,图像对象和其他元素。2. 在Engine.onCreate()方法中初始化表盘元素。3. 在Engine.onVisibilityChanged()方法中初始化自定义的定时器。初始化变量当系统加载你的service的时候,会在不同的实现地方访问你所初始化的资源,所以你可以复用它们。你可以在你的WatchFaceService.Engine实现中声明这些资源变量。为下面这些元素声明变量:图像对象大部分表盘至少包含一个bitmap图片作为表盘背景图,你可以使用其他bitmap图片来呈现时钟指针或其他表盘设计元素。定时器当时间改变的时候系统每分钟通知一次表盘,但一些表盘会在自定义的时间间隔下显示动画。在这些案例中,你需要提供一个自定义的定时器来频繁刷新你的表盘。时区变化receiver当用户在旅行途中他们可以自适应时区,系统会发送事件广播。你的service必须注册一个广播的receiver,当时区发生改变和更新的时候会受到通知。在表盘代码示例中的AnalogWatchFaceService.Engine类简单的定义了这些变量。自定义定时器实现了一个handler实例,使用线程消息队列来发送和处理延迟消息。在这个表盘示例中,自定义的定时器每秒触发一次。当定时器触发的时候,handler会调用invalid()方法,并且系统之后会调用ondraw()方法来重绘表盘。private class Engine extends CanvasWatchFaceService.Engine static final int MSG_UPDATE_TIME = 0;/* a time object */Time mTime;/* device features */boolean mLowBitAmbient;/* graphic objects */Bitmap mBackgroundBitmap;Bitmap mBackgroundScaledBitmap;Paint mHourPaint;Paint mMinutePaint;./* handler to update the time once a second in interactive mode */final Handler mUpdateTimeHandler = new Handler() Overridepublic void handleMessage(Message message) switch (message.what) case MSG_UPDATE_TIME:invalidate();if (shouldTimerBeRunning() long timeMs = System.currentTimeMillis();long delayMs = INTERACTIVE_UPDATE_RATE_MS- (timeMs % INTERACTIVE_UPDATE_RATE_MS);mUpdateTimeHandler.sendEmptyMessageDelayed(MSG_UPDATE_TIME, delayMs);break;/* receiver to update the time zone */final BroadcastReceiver mTimeZoneReceiver = new BroadcastReceiver() Overridepublic void onReceive(Context context, Intent intent) mTime.clear(intent.getStringExtra(time-zone);mTime.setToNow();/* service methods (see other sections) */.初始化表盘元素在你为bitmap资源,paint对象类型,以及其他你每次重绘表盘都需要复用的元素声明了成员变量后, 在系统加载你的service时初始化它们。只需要初始化一次这些元素并复用他们,这样可以提高性能和电池续航。在Engine.onCreate()方法里,初始化以下元素: 加载背景图 创建样式和颜色来绘制图形对象 分配一个time对象的引用 配置系统UIAnalogWatchFaceService类中的Engine.onCreate()方法初始化了这些元素:Overridepublic void onCreate(SurfaceHolder holder) super.onCreate(holder);/* configure the system UI (see next section) */./* load the background image */Resources resources = AnalogWatchFaceService.this.getResources();Drawable backgroundDrawable = resources.getDrawable(R.drawable.bg);mBackgroundBitmap = (BitmapDrawable) backgroundDrawable).getBitmap();/* create graphic styles */mHourPaint = new Paint();mHourPaint.setARGB(255, 200, 200, 200);mHourPaint.setStrokeWidth(5.0f);mHourPaint.setAntiAlias(true);mHourPaint.setStrokeCap(Paint.Cap.ROUND);./* allocate an object to hold the time */mTime = new Time();当系统初始化表盘的时候背景图只需要加载一次。初始化自定义定时器作为表盘开发者,你要决定你的表盘多久刷新,当设备处于交互模式下利用自定义的定时器来触发频繁更新。这样还能让你创建自定义动画和其他视觉效果。注意:在环境模式下,系统不一定会调用自定义定时器。在AnalogWatchFaceService 类中定义的示例定时器,每秒钟会触发显示一次声明的变量资源。在Engine.onVisibilityChanged()方法中,如果两个条件同时满足了就会启动自定义定时器: 表盘可见设备处于交互模式private void updateTimer() mUpdateTimeHandler.removeMessages(MSGUPDATETIME); if (shouldTimerBeRunning() mUpdateTimeHandler.sendEmptyMessage(MSGUPDATETIME); private boolean shouldTimerBeRunning() return isVisible() & !isInAmbientMode(); 在Engine.onVisibilityChanged()方法中,启动定时器并注册时区变化的receiver:Overridepublic void onVisibilityChanged(boolean visible) super.onVisibilityChanged(visible);if (visible) registerReceiver();/ Update time zone in case it changed while we werent visible.mTime.clear(TimeZone.getDefault().getID();mTime.setToNow(); else unregisterReceiver();/ Whether the timer should be running depends on whether were visible and/ whether were in ambient mode), so we may need to start or stop the timerupdateTimer();当表盘不可见时,停止自定义的定时器并且注销时区变化的receiver。private void registerReceiver() if (mRegisteredTimeZoneReceiver) return;mRegisteredTimeZoneReceiver = true;IntentFilter filter = new IntentFilter(Intent.ACTION_TIMEZONE_CHANGED);AnalogWatchFaceService.this.registerReceiver(mTimeZoneReceiver, filter);private void unregisterReceiver() if (!mRegisteredTimeZoneReceiver) return;mRegisteredTimeZoneReceiver = false;AnalogWatchFaceService.this.unregisterReceiver(mTimeZoneReceiver);在环境模式下刷新表盘在环境模式下,系统每分钟调用一次 Engine.onTimeTick()方法。在这个模式下,每分钟刷新一次表盘足够了。在环境模式下,大部分表盘只要在Engine.onTimeTick()方法中简单调用invalidate方法就可以重绘你的表盘。Overridepublic void onTimeTick() super.onTimeTick();invalidate();配置系统UI表盘不应该干扰系统UI元素。如果你的表盘有个亮的背景或者在屏幕底部要显示信息,你就必须配置通知卡片的大小,或者开启背景保护。当你的表盘处于激活状态,Android Wear能让你配置以下几方面系统UI: 指定第一个通知卡片在屏幕中的范围 指定系统是否在你的表盘上绘制时间 在环境模式下显示或隐藏卡片 用一个实体背景来包裹系统指示器 指定系统指示器位置为了配置系统UI的这些方面,创建一个WatchFaceStyle实例并把它传给Engine.setWatchFaceStyle()方法。Overridepublic void onCreate(SurfaceHolder holder) super.onCreate(holder);/* configure the system UI */setWatchFaceStyle(new WatchFaceStyle.Builder(AnalogWatchFaceService.this).setCardPeekMode(WatchFaceStyle.PEEK_MODE_SHORT).setBackgroundVisibility(WatchFaceStyle.BACKGROUND_VISIBILITY_INTERRUPTIVE).setShowSystemUiTime(false).build();.上面的代码片段配置了以单行高度显示通知卡片,卡片的背景只会简单的显示且只用于终止通知,并且系统时间不会显示(这样表盘需要自己绘制时间)。在你的表盘实现中,你可以在任何地方配置系统UI风格。例如如果用户选择了一个白色背景,你可以为系统指示器添加背景保护。更多详情可以查看WatchFaceStyle类的API reference获取设备屏幕信息当系统确定了设备屏幕属性后会调用Engine.onPropertiesChanged()方法,例如设备是否使用了低比特的环境模式,以及屏幕是否需要老化保护。Overridepublic void onPropertiesChanged(Bundle properties) super.onPropertiesChanged(properties);mLowBitAmbient = properties.getBoolean(PROPERTY_LOW_BIT_AMBIENT, false);mBurnInProtection = properties.getBoolean(PROPERTY_BURN_IN_PROTECTION,false);当你绘制表盘的时候,你需要考虑到这些设备属性: 当设备使用了低比特环境模式,屏幕只支持更少的位颜色,所以你需要关闭抗锯齿。 当设备需要老化保护,在环境模式下避免使用大块的白色像素,并且不要把内容放进屏幕10像素的边框中,因为系统会定时的变化内容来防止像素老化。(这有点像windows电脑屏保的作用)响应模式切换当设备在环境模式和交互模式间切换时,系统会调用Engine.onAmbientModeChanged()方法。你的service需要自适应模式间的切换,并且调用invalidate方法来让系统重绘你的表盘。Overridepublic void onAmbientModeChanged(boolean inAmbientMode) super.onAmbientModeChanged(inAmbientMode);if (mLowBitAmbient) boolean antiAlias = !inAmbientMode;mHourPaint.setAntiAlias(antiAlias);mMinutePaint.setAntiAlias(antiAlias);mSecondPaint.setAntiAlias(antiAlias);mTickPaint.setAntiAlias(antiAlias);invalidate();updateTimer();绘制表盘为了绘制自定义表盘,系统会调用Engine.onDraw()方法,并传入一个Canvas示例和Rect示例,Rect表示你绘制表盘的区域。你可以使用这个canvas对象来直接绘制你的表盘:1. 如果是第一次调用onDraw()方法,缩放背景来适应屏幕2. 检测设备是在环境模式还是交互模式3. 执行任何需要的图形计算4. 绘制背景bitmap到canvas上5.使用Canvas类的方法来绘制表盘6.Override public void onDraw(Canvas canvas, Rect bounds) / Update the time mTime.setToNow();7.int width = bounds.width(); int height = bounds.height();8./ Draw the background, scaled to fit. if (mBackgroundScaledBitmap = null | mBackgroundScaledBitmap.getWidth() != width | mBackgroundScaledBitmap.getHeight() != height) mBackgroundScaledBitmap = Bitmap.createScaledBitmap(mBackgroundBitmap, width, height, true /* filter */); canvas.drawBitmap(mBackgroundScaledBitmap, 0, 0, null);9./ Find the center. Ignore the window insets so that, on round watches / with a chin, the watch face is centered on the entire screen, not / just the usable portion. float centerX = width / 2f; float centerY = height / 2f;10./ Compute rotations and lengths for the clock hands. float secRot = mTime.second / 30f * (float) Math.PI; int minutes = mTime.minute; float minRot = minutes / 30f * (float) Math.PI; float hrRot = (mTime.hour + (minutes / 60f) / 6f ) * (float) Math.PI;11.flo

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论