现在的位置: 首页 > 综合 > 正文

Gallery3d 学习笔记(6)

2013年08月22日 ⁄ 综合 ⁄ 共 4632字 ⁄ 字号 评论关闭

继续讲解前,我们先回顾一下前面5节的分析。

首先在开机或者加载外部存储器时,在mediaprivder里面receiver会得到广播消息,receiver开启服务进行扫描,生成数据库,并在T卡上生成缩略图临时文件,

然后在第一个Activity里面有两个关于opengl的成员,RenderView和作为Root Layer 的GridLayer成员,并且关联了RenderView和Root Layer,并且在Activity里面通过调用RenderView的同名成员函数的办法,将按键响应以及渲染的暂停和继续同Activity同步关联。

而RenderView在刷新时,通过调用generate接口,生成Root层的,Root层调用generate接口生成背景层和Hud层,同样的办法Hud层生成其他的层,并将RendView保存到自己的成员变量中。

而这些层又分成了几个类,放在几个层的列表中,决定哪些层响应点击事件,哪些层透明。

现在我们要分析的问题是,界面和层是如何关联的,又是如何切换的?

这个问题比较多,会花几个部分解决。

我们先探讨一个小的问提,我们先使用下Gallery3d ,你会发现长按键后可以标记相册或者单一图片或者视频。

说明Gallery3d里面又两种模式,普通模式和选择模式对应的代码是在HudLayer中:

public final class HudLayer extends Layer {
    public static final int MODE_NORMAL = 0;
    public static final int MODE_SELECT = 1;

那么在关键的HudLayer中又用了两个方法来读取和设置模式

    int getMode() {
        return mMode;
    }

    void setMode(int mode) {
        if (mMode != mode) {
            mMode = mode;
            updateViews();
        }
    }

在哪里调用的呢

    public void enterSelectionMode() {
        // Do not enter selection mode if the feed is about to change.
        if (mGridLayer.feedAboutToChange())
            return;
        // Disable sharing if it is the pick intent.
        if (mGridLayer.getPickIntent()) {
            mSingleViewIntentBottomMenu = mSingleViewIntentBottomMenuNoShare;
            mNormalBottomMenu = mNormalBottomMenuNoShare;
        }
        setAlpha(1.0f);
        setMode(HudLayer.MODE_SELECT);
        // if we are in single view mode, show the bottom menu without the
        // delete button.
        if (mGridLayer.noDeleteMode()) {
            mSelectionMenuBottom.setMenus(mSingleViewIntentBottomMenu);
        } else {
            mSelectionMenuBottom.setMenus(mNormalBottomMenu);
        }
    }

    public void cancelSelection() {
        mSelectionMenuBottom.close();
        closeSelectionMenu();
        setMode(MODE_NORMAL);
    }

就是通过HudLayer中的进入选择模式和退出选择模式来切换模式的和菜单的显示。那么从用户长按又是如何到enterSelectMode函数的呢?

首先触摸是各个层里面处理的,而按键都是Root Layer处理的,谁是Root Layer,当然是GridLayer,我们看下GridLayer是如何处理的

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return mInputProcessor.onTouchEvent(event);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (mInputProcessor != null)
            return mInputProcessor.onKeyDown(keyCode, event, mState);
        return false;
    }

说明所有GridLayer的按键和触摸都交给了一个叫做mInputProcessor的成员去处理了。对应的是

GridInputProcessor类

这个类又是如何处理的呢?

 public void onLongPress(MotionEvent e) {
        if (mZoomGesture)
            return;
        if (mLayer.getFeed() != null && mLayer.getFeed().isSingleImageMode()) {
            HudLayer hud = mLayer.getHud();
            hud.getPathBar().setHidden(true);
            hud.getMenuBar().setHidden(true);
            if (hud.getMode() != HudLayer.MODE_NORMAL)
                hud.setMode(HudLayer.MODE_NORMAL);
        }
        if (mCurrentFocusSlot != Shared.INVALID) {
            vibrateLong();
            GridLayer layer = mLayer;
            if (layer.getState() == GridLayer.STATE_FULL_SCREEN) {
                layer.deselectAll();
            }
            HudLayer hud = layer.getHud();
            hud.enterSelectionMode();
            layer.addSlotToSelectedItems(mCurrentFocusSlot, true, true);
        }
    }

那么,我们重新整理下思路:

用户长按 Activity --> 因为Acitvity中的触摸是层里面处理的,所以给了根层GridLayer去处理,而GridLayer嫌麻烦,另外写了一个类GridInputProcessor的成员处理,而再这个类中,调用通过传进来的GridLayer上下文和方法 getHud获得了Hud层的对象,然后调用他的enterSelectionMode方法,将状态设置成了选择模式。

长按和处理我们看完了,其他的拖动和点击请自己再分析下,作为今天的作业吧,呵呵。

那么我们再来看GridLayer界面的显示,再构造函数我们可以看到下面的代码。

        mCameraManager = new GridCameraManager(mCamera);
        mDrawManager = new GridDrawManager(context, mCamera, mDrawables, mDisplayList, mDisplayItems, mDisplaySlots);
        mInputProcessor = new GridInputProcessor(context, mCamera, this, mView, mTempVec, mDisplayItems);

mDrawManager就是负责界面的显示的。我们仔细看下。

大家还记得RenderView里面对三组层的列表进行的统一刷新么?

其中对opaque层是怎么刷新的,使用的是一个循环,加上调用层的renderOpaque方法,那么我们来看这个里面是否有?我们看GridLayer层的刷新函数

    // Renders the node in a given pass.
    public void renderOpaque(RenderView view, GL11 gl) {
        GridCamera camera = mCamera;
        int selectedSlotIndex = mInputProcessor.getCurrentSelectedSlot();
        computeVisibleItems();

        gl.glMatrixMode(GL11.GL_MODELVIEW);
        gl.glLoadIdentity();
        GLU.gluLookAt(gl, -camera.mEyeX, -camera.mEyeY, -camera.mEyeZ, -camera.mLookAtX, -camera.mLookAtY, -camera.mLookAtZ,
                camera.mUpX, camera.mUpY, camera.mUpZ);
        view.setAlpha(1.0f);
        if (mSelectedAlpha != 1.0f) {
            gl.glEnable(GL11.GL_BLEND);
            gl.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
            view.setAlpha(mSelectedAlpha);
        }
        if (selectedSlotIndex != Shared.INVALID) {
            mTargetAlpha = 0.0f;
        } else {
            mTargetAlpha = 1.0f;
        }
        mDrawManager.prepareDraw(mBufferedVisibleRange, mVisibleRange, selectedSlotIndex, mInputProcessor.getCurrentFocusSlot(),
                mInputProcessor.getCurrentScaledSlot(), mInputProcessor.isFocusItemPressed(), mInputProcessor.getScale(),
                mInputProcessor.getScaleGestureDetector(), mFeedAboutToChange);
        if (mSelectedAlpha != 0.0f) {
            mDrawManager.drawThumbnails(view, gl, mState);
        }
        if (mSelectedAlpha != 1.0f) {
            gl.glDisable(GL11.GL_BLEND);
        }
        // We draw the selected slotIndex.
        if (selectedSlotIndex != Shared.INVALID) {
            mDrawManager.drawFocusItems(view, gl, mZoomValue, mSlideshowMode, mTimeElapsedSinceView);
            mCurrentFocusItemWidth = mDrawManager.getFocusQuadWidth();
            mCurrentFocusItemHeight = mDrawManager.getFocusQuadHeight();
        }
        view.setAlpha(mSelectedAlpha);
    }

在这里面,我们找到了实质性刷界面的函数

ComputerVisibleItem();计算可见项目

mDrawManager.prepareDraw准备工作

mDrawManager.drawThumnails画缩略图

在这里我们看到了缩略图显示刷新,但是还有一些疑问,数据从哪里来的,而且这里只有一个界面的显示,其他的界面如何显示的?下次探讨吧。

抱歉!评论已关闭.