这似乎是,我不能让我试图达到的效果的原因是因为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;
}
编辑:按照要求,我想提供一些额外的输入至于如何调整纹理一个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];
}
,但只能从Renderer
类中和我来说,我一直等到纹理的onDrawFrame内做这项工作;在一个位图被分配给它之前。
然后,为我加载的Bitmap
的目标是在没有内存不足的情况下简单加载我所能够加载的内容。为此,我简单地修改了我即将加载的Bitmap的Options
,并尝试在try catch块中加载它。如果内存耗尽,我会再试一次,但占用的空间较小。
try
{
final int sizeFactors[] = { 1, 2, 4, 8, 16, 32 };
if (new File(bitmapFilePath).exists())
{
BitmapFactory.Options options = new BitmapFactory.Options();
for (int i = 0; i < sizeFactors.length; ++i)
{
try
{
options.inSampleSize = sizeFactors[i];
Bitmap bmp = BitmapFactory.decodeFile(bitmapFilePath, options);
if(bmp.getHeight() > maximumTextureSize ||
bmp.getWidth() > maximumTextureSize)
{
continue;
}
/*
* @category Check against EXIF data if the image needs to be rotated or not for viewing.
*/
Matrix matrix = new Matrix();
ExifInterface exif = new ExifInterface(bitmapFilePath);
int orientation = exif.getAttributeInt (ExifInterface.TAG_ORIENTATION, 1);
switch(orientation)
{
case ExifInterface.ORIENTATION_NORMAL:
break;
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.postRotate (90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.postRotate (180);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.postRotate (270);
break;
default:
}
bmp = Bitmap.createBitmap (bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
return bmp;
} catch (OutOfMemoryError outOfMemory)
{
//Do nothing, it will return when one that doesn't run out of memory is loaded. Or you could do additional checking to bail if needed, etc.
}
}
throw new Exception("Not enough memory for loading image");
}
} catch (Exception exception)
{
Log.e("CustomLogTag", "Exception for loading the image that was selected for extraction.");
}
有很多方法可以做到这一点,但这是采取一个办法,我想补充的清晰度和附加信息,这个以前的职位的要求,因为它没有包含在我接受的答案为尽可能多的信息我会喜欢任何一个。
你解决了你的问题吗?我有同样的问题,但无法修复它... – 2015-01-30 14:18:33
@alexlodoss我提供的上述代码最终为我工作。我在SurfaceView后面的ImageView中有一张低分辨率照片。所以,当ViewPager被交互时,会显示低分辨率的“位图”,当它结束时,我会将“SurfaceView”带回可视范围。 – 2015-01-30 20:21:23
请告诉我,当你获得类BitmapFactoryUtils?我没有注意到它在第一次... – 2015-02-02 11:23:16