谷歌眼镜GDK开发指南之动态卡片

原文地址:http://bbs.seacat.cn/thread-896-1-1.html




动态卡片出现在时间轴的现在和将来区域,显示当前时间段的关联信息。

你可以低频率的渲染动态卡片,几秒一次更新。或者高频率,一秒更新几次。

动态卡片的构建


动态卡片会长时间运行,所以需要一个后台服务来管理。


142728nmp474ffxcxxz914.png




你可以在服务启动或者其他监听事件触发的时候显示一张活动卡片,当活动卡片不再相关的时候,销毁服务停止渲染。


低频率渲染

低频率渲染仅限制于少数的android view 且几秒钟才能更新一次。

这是最简单创建动态卡片的方式,内容简单,不用不停的渲染。

143345z33esg0jzi0iv3s2.png




高频率渲染

它比低频率渲染调用的次数多,但也能提供更多功能特性。

143605q71vr51rr67v8831.png






创建低频率动态卡片



低频率渲染需要一个 RemoteViews对象提供UI,支持以下Android layouts 和 views:


FrameLayout
LinearLayout
RelativeLayout
GridLayout


AdapterViewFlipper
AnalogClock
Button
Chronometer


GridView
ImageButton
ImageView
ListView


ProgressBar
StackView
TextView
ViewFlipper




当以下情况使用低频率渲染:
1、你只需要标准的Android views APIs ,不需要高级渲染
2、你只需要相对较少刷新(几秒刷新一下)




记住:


1、对于时间轴动态卡片一定需要调用 setAction() 传入一个 PendingIntent
2、当发布之后,如果发现改变,调用setViews() 来再次更新布局



[java] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // Tag used to identify the LiveCard in debugging logs.

  2. privatestaticfinal String LIVE_CARD_TAG = "my_card";  

  3. // Cached instance of the LiveCard created by the publishCard() method.

  4. private LiveCard mLiveCard;  

  5. privatevoid publishCard(Context context) {  

  6. if (mLiveCard == null) {  

  7.        TimelineManager tm = TimelineManager.from(context);  

  8.        mLiveCard = tm.createLiveCard(LIVE_CARD_TAG);  

  9.        mLiveCard.setViews(new RemoteViews(context.getPackageName(),  

  10.                R.layout.card_text));  

  11.        Intent intent = new Intent(context, EntryActivity.class);  

  12.        mLiveCard.setAction(PendingIntent.getActivity(context, 0,  

  13.                intent, 0));  

  14.        mLiveCard.publish(LiveCard.PublishMode.SILENT);  

  15.    } else {  

  16. // Card is already published.

  17. return;  

  18.    }  

  19. }  

  20. privatevoid unpublishCard(Context context) {  

  21. if (mLiveCard != null) {  

  22.        mLiveCard.unpublish();  

  23.        mLiveCard = null;  

  24.    }  

  25. }  







创建高频率动态卡片

高频率动态卡片能让你直接绘图。这种渲染更灵活且能让你是用所有的Android graphics




当以下情况时使用高频率动态卡片:


1、你需要频繁更新动态卡片(一秒更新几次)
2、你能更灵活的渲染。 RemoteViews 只支持渲染一个布局,直接渲染能让你使用更多的graphics功能。




牢记:

1、你应该创建一个后台服务来渲染活动卡片的surface
2、使用surfaceCreated() 和 surfaceDestroyed() 来显示或隐藏卡片
3、 surface holder的回调方法不要在主线程调用
4、动态卡片一定需要调用 setAction() 传入一个 PendingIntent




使用高频率渲染:


1、创建一个实现 DirectRenderingCallback 的类:



[java] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. publicclass LiveCardRenderer implements DirectRenderingCallback {  

  2. // About 30 FPS.

  3. privatestaticfinallong FRAME_TIME_MILLIS = 33;  

  4. private SurfaceHolder mHolder;  

  5. privateboolean mPaused;  

  6. private RenderThread mRenderThread;  

  7. @Override

  8. publicvoid surfaceChanged(SurfaceHolder holder, int format, int width, int height) {  

  9. // Update your views accordingly.

  10.    }  

  11. @Override

  12. publicvoid surfaceCreated(SurfaceHolder holder) {  

  13.        mHolder = holder;  

  14.        updateRendering();  

  15.    }  

  16. @Override

  17. publicvoid surfaceDestroyed(SurfaceHolder holder) {  

  18.        mHolder = null;  

  19.        updateRendering();  

  20.    }  

  21. @Override

  22. publicvoid renderingPaused(SurfaceHolder holder, boolean paused) {  

  23.        mPaused = paused;  

  24.        updateRendering();  

  25.    }  

  26. /**

  27.     * Start or stop rendering according to the timeline state.

  28.     */

  29. privatesynchronizedvoid updateRendering() {  

  30. boolean shouldRender = (mHolder != null) && !mPaused;  

  31. boolean rendering = mRenderThread != null;  

  32. if (shouldRender != rendering) {  

  33. if (shouldRender) {  

  34.                mRenderThread = new RenderThread();  

  35.                mRenderThread.start();  

  36.            } else {  

  37.                mRenderThread.quit();  

  38.                mRenderThread = null;  

  39.            }  

  40.        }  

  41.    }  

  42. /**

  43.     * Draws the view in the SurfaceHolder's canvas.

  44.     */

  45. privatevoid draw(View view) {  

  46.        Canvas canvas;  

  47. try {  

  48.            canvas = mHolder.lockCanvas();  

  49.        } catch (Exception e) {  

  50. return;  

  51.        }  

  52. if (canvas != null) {  

  53. // Draw on the canvas.

  54.            mHolder.unlockCanvasAndPost(canvas);  

  55.        }  

  56.    }  

  57. /**

  58.     * Redraws in the background.

  59.     */

  60. privateclass RenderThread extends Thread {  

  61. privateboolean mShouldRun;  

  62. /**

  63.         * Initializes the background rendering thread.

  64.         */

  65. public RenderThread() {  

  66.            mShouldRun = true;  

  67.        }  

  68. /**

  69.         * Returns true if the rendering thread should continue to run.

  70.         *

  71.         * @return true if the rendering thread should continue to run

  72.         */

  73. privatesynchronizedboolean shouldRun() {  

  74. return mShouldRun;  

  75.        }  

  76. /**

  77.         * Requests that the rendering thread exit at the next opportunity.

  78.         */

  79. publicsynchronizedvoid quit() {  

  80.            mShouldRun = false;  

  81.        }  

  82. @Override

  83. publicvoid run() {  

  84. while (shouldRun()) {  

  85.                draw();  

  86.                SystemClock.sleep(FRAME_TIME_MILLIS);  

  87.            }  

  88.        }  

  89.    }  

  90. }  





2、设置你的类的实例作为 LiveCard SurfaceHolder 的回调:



[java] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // Tag used to identify the LiveCard in debugging logs.

  2. privatestaticfinal String LIVE_CARD_TAG = "my_card";  

  3. // Cached instance of the LiveCard created by the publishCard() method.

  4. private LiveCard mLiveCard;  

  5. privatevoid publishCard(Context context) {  

  6. if (mLiveCard == null) {  

  7.        TimelineManager tm = TimelineManager.from(context);  

  8.        mLiveCard = tm.createLiveCard(LIVE_CARD_TAG);  

  9. // Enable direct rendering.

  10.        mLiveCard.setDirectRenderingEnabled(true);  

  11.        mLiveCard.getSurfaceHolder().addCallback(new RenderThread());  

  12.        Intent intent = new Intent(context, MenuActivity.class);  

  13.        mLiveCard.setAction(PendingIntent.getActivity(context, 0,  

  14.                intent, 0));  

  15.        mLiveCard.publish(LiveCard.PublishMode.SILENT);  

  16.    } else {  

  17. // Card is already published.

  18. return;  

  19.    }  

  20. }  

  21. privatevoid unpublishCard(Context context) {  

  22. if (mLiveCard != null) {  

  23.        mLiveCard.unpublish();  

  24.        mLiveCard = null;  

  25.    }  

  26. }  





这个实例使用一个后台线程周期性的渲染,但你也可以响应外部事件来刷新卡片(例如传感器或地理位置更新)。




静默发布活动卡片



上面的例子传入LiveCard.PublishMode.REVEAL 到 LiveCard.publish() 方法中可以直接显示卡片。当你的Glassware的主界面是一张活动卡片时这样很有用。



通过使用 LiveCard.PublishMode.SILENT ,你也可以从后台创建一张活动卡片。用户也能在时间轴中看到它。


你可能感兴趣的:(android)