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

来源:互联网 发布:加工中心键槽编程实例 编辑:程序博客网 时间:2024/05/04 05:44

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




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

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

动态卡片的构建


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





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


低频率渲染

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

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




高频率渲染

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






创建低频率动态卡片


低频率渲染需要一个 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() 来再次更新布局


// Tag used to identify the LiveCard in debugging logs.private static final String LIVE_CARD_TAG = "my_card"; // Cached instance of the LiveCard created by the publishCard() method.private LiveCard mLiveCard; private void publishCard(Context context) {    if (mLiveCard == null) {        TimelineManager tm = TimelineManager.from(context);        mLiveCard = tm.createLiveCard(LIVE_CARD_TAG);         mLiveCard.setViews(new RemoteViews(context.getPackageName(),                R.layout.card_text));        Intent intent = new Intent(context, EntryActivity.class);        mLiveCard.setAction(PendingIntent.getActivity(context, 0,                intent, 0));        mLiveCard.publish(LiveCard.PublishMode.SILENT);    } else {        // Card is already published.        return;    }} private void unpublishCard(Context context) {    if (mLiveCard != null) {        mLiveCard.unpublish();        mLiveCard = null;    }}






创建高频率动态卡片

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




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


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




牢记:

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




使用高频率渲染:


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


public class LiveCardRenderer implements DirectRenderingCallback {     // About 30 FPS.    private static final long FRAME_TIME_MILLIS = 33;     private SurfaceHolder mHolder;    private boolean mPaused;    private RenderThread mRenderThread;     @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {        // Update your views accordingly.    }     @Override    public void surfaceCreated(SurfaceHolder holder) {        mHolder = holder;        updateRendering();    }     @Override    public void surfaceDestroyed(SurfaceHolder holder) {        mHolder = null;        updateRendering();    }     @Override    public void renderingPaused(SurfaceHolder holder, boolean paused) {        mPaused = paused;        updateRendering();    }     /**     * Start or stop rendering according to the timeline state.     */    private synchronized void updateRendering() {        boolean shouldRender = (mHolder != null) && !mPaused;        boolean rendering = mRenderThread != null;         if (shouldRender != rendering) {            if (shouldRender) {                mRenderThread = new RenderThread();                mRenderThread.start();            } else {                mRenderThread.quit();                mRenderThread = null;            }        }    }     /**     * Draws the view in the SurfaceHolder's canvas.     */    private void draw(View view) {        Canvas canvas;        try {            canvas = mHolder.lockCanvas();        } catch (Exception e) {            return;        }        if (canvas != null) {            // Draw on the canvas.            mHolder.unlockCanvasAndPost(canvas);        }    }     /**     * Redraws in the background.     */    private class RenderThread extends Thread {        private boolean mShouldRun;         /**         * Initializes the background rendering thread.         */        public RenderThread() {            mShouldRun = true;        }         /**         * Returns true if the rendering thread should continue to run.         *         * @return true if the rendering thread should continue to run         */        private synchronized boolean shouldRun() {            return mShouldRun;        }         /**         * Requests that the rendering thread exit at the next opportunity.         */        public synchronized void quit() {            mShouldRun = false;        }         @Override        public void run() {            while (shouldRun()) {                draw();                SystemClock.sleep(FRAME_TIME_MILLIS);            }        }    }}



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


// Tag used to identify the LiveCard in debugging logs.private static final String LIVE_CARD_TAG = "my_card"; // Cached instance of the LiveCard created by the publishCard() method.private LiveCard mLiveCard; private void publishCard(Context context) {    if (mLiveCard == null) {        TimelineManager tm = TimelineManager.from(context);        mLiveCard = tm.createLiveCard(LIVE_CARD_TAG);         // Enable direct rendering.        mLiveCard.setDirectRenderingEnabled(true);        mLiveCard.getSurfaceHolder().addCallback(new RenderThread());         Intent intent = new Intent(context, MenuActivity.class);        mLiveCard.setAction(PendingIntent.getActivity(context, 0,                intent, 0));        mLiveCard.publish(LiveCard.PublishMode.SILENT);    } else {        // Card is already published.        return;    }} private void unpublishCard(Context context) {    if (mLiveCard != null) {        mLiveCard.unpublish();        mLiveCard = null;    }}



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




静默发布活动卡片



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



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

0 0
原创粉丝点击