隐藏ImageView的GLSurfaceView不受欢迎

时间:2013-04-11 21:03:32

标签: android opengl-es

有一个带有' match_parent'的ImageView和GLSurfaceView设置。屏幕上的参数。 ImageView会快速填充并显示在屏幕上。然后,GLSurfaceView将在其上方填充并修改图像。到目前为止一切都很好。

但是,这些视图也存在于ViewPager内部,其左侧和右侧都有图像。在ImageView顶部引入OpenGL Surface View之前,视图将按预期向左和向右过渡。但是在将GLSurfaceView引入其上之后,只要用户开始滑动手指移动到下一个图像,SurfaceView就会变得透明,导致图像消失。它甚至强制它下面的图像在ImageView中消失。显示父视图的背景。

我不清楚如何处理这个问题。如果纹理像ImageView一样向侧面滑动,或者甚至是透明的,但将ImageView放在后面看起来会很好。

即使GLSurfaceView.RENDERMODE_CONTINUOSLY在转换过程中也不会保持纹理。

1 个答案:

答案 0 :(得分:1)

似乎我无法获得我想要实现的效果的原因是因为GLSurfaceView总是放在其他视图后面,导致前景视图的透明度。因此,GLSurfaceView优先于被绘制。为了达到我想要的效果,我可能需要确保在刷卡时使用View.setVisibility()进行隐藏,并在ViewPager结算后将其设置为可见。这是我在看到其他几个链接作为不同研究的副产品之后遇到的当前结论。

z-order for GLSurfaceViews

scrolling in GLSurfaceViews

似乎GLSurfaceView类的表现与我原先预期的类似。因此,需要进一步注意,以便进一步保持ImageView在ViewPager中的图像之间可见的过渡。

在viewPager中,我设法完成了以下代码的操作。当然,由于处于测试阶段,它仍处于粗略状态,但它完成了我正在寻找的东西。当我们开始在图像上定位时,纹理开始加载,然后在用户开始离开图像后消失,露出原始图像。这似乎可以在没有撕裂或闪烁的情况下工作,这就是我对它的行为所期望的。

@Override
public void onPageScrollStateChanged(int state)
{
    switch(state)
    {
        case ViewPager.SCROLL_STATE_DRAGGING:
            Log.i("photoViewer:","dragging ViewPager");
            if(photoSurfaceView_ != null  && photoViewFrameLayout != null)
            {
                photoSurfaceView_.setAlpha(0);
                photoSurfaceView_.invalidate();
            }
            break;
        case ViewPager.SCROLL_STATE_IDLE:
            photoSurfaceView_.setVisibility(View.VISIBLE);
            photoSurfaceView_.setAlpha(1);
            Log.i("photoViewer:","idle ViewPager");
            break;
        case ViewPager.SCROLL_STATE_SETTLING:
            int childCount = photoViewFrameLayout.getChildCount();
            if(childCount >= 2)
            {
                photoViewFrameLayout.removeViews(1, childCount-1);
            }
            new Thread(new Runnable() {
                @Override
                public void run()
                {
                    Looper.prepare();
                    final Bitmap openGlBitmap = BitmapFactoryUtils.resizeAsNecessaryForOpenGLtexture(photoPaths[photoViewPager_.getCurrentItem()], new BitmapFactory.Options());
                    Rect bounds = BitmapFactoryUtils.calculateBoundsForBitmap(activityContext, openGlBitmap);
                    int scaledHeight = bounds.height();
                    int scaledWidth = bounds.width();
                    photoSurfaceView_ = new PhotoViewSurfaceView(activityContext, openGlBitmap);
                    photoSurfaceView_.setLayoutParams(new LayoutParams(scaledWidth, scaledHeight, Gravity.CENTER));
                    photoSurfaceView_.setVisibility(View.VISIBLE);
                    photoSurfaceView_.setAlpha(0);
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run()
                        {
                            photoViewFrameLayout.addView(photoSurfaceView_);
                        }
                    });
                }
            }).start();

            Log.i("photoViewer:","settling ViewPager");
            break;
    }

编辑: 根据要求,我想提供一些额外的输入,说明如何调整使用{{1}的OpenGL SurfaceView的纹理输入。

以下是该过程第一步可用的一些代码的快速摘要,用于检查当前位图的纹理大小是否适合单个纹理。如果你想平铺纹理以保持图像更大,那么这会变得更复杂,这不是我的解决方案所需要的。

可以使用以下代码检索纹理大小:

Bitmap

但仅限于private void assignTextureSize() { /* The maximum texture size can be found within the OpenGL context and then shared amongst other applications. */ int[] maxTextureSize = new int[1]; GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, maxTextureSize, 0); maxTextureSize = maxTextureSize[0]; } 类中,对于我的情况,我一直等到Texture的onDrawFrame中进行赋值;在为其分配位图之前。

然后,为我加载的Renderer的目标是简单地加载我能够做到的而不会耗尽内存。为此,我只是修改了我要加载的Bitmap的Bitmap,并尝试在try catch块中加载它。如果内存不足,我会再次尝试,但占用空间较小。

Options

有很多方法可以实现这一目标,但这是一种方法,我希望按照要求在上一篇文章中添加清晰度和附加信息,因为它没有包含尽可能多的关于我接受的答案的信息,因为我希望任