Вид через GLSurfaceView мерцает или не отображается вообще - PullRequest
1 голос
/ 11 ноября 2011

Мы используем ViewGroup, содержащий большое GLSurfaceView и маленькое представление. Вид рисуется поверх GLSurfaceView. Вид виден при перетаскивании, но он исчезает, как только движение заканчивается и палец освобождается от планшета. Мы обнаружили, что это происходит только в том случае, если установлено значение setRenderMode(RENDERMODE_WHEN_DIRTY). Он работает, когда изображение отображается непрерывно, но это очень плохо сказывается на производительности.

При использовании RelativeLayout вместо ViewGroup вид отображается после того, как палец отпущен от планшета, но мигает при медленном перемещении вида.

Невозможно нарисовать представление с помощью OpenGL, потому что GLSurfaceView не заполняет всю ViewGroup, и представление можно перемещать по всей ViewGroup.

Вот полный пример, который показывает проблему:

package test.gl.app;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.app.Activity;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;

public class GLTestAppActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mGLViewGroup = new GLViewGroup(this);
        setContentView(mGLViewGroup);
    }

    @Override
    protected void onPause() {
        super.onPause();
        mGLViewGroup.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mGLViewGroup.onResume();
    }

    private GLViewGroup mGLViewGroup;
}



class ImageView extends View {

    private Drawable _drawable;

    public ImageView(Context context) {
        super(context);
        _drawable = new BitmapDrawable(BitmapFactory.decodeResource(context.getResources(), R.drawable.icon_192));
        _drawable.setBounds(0,0,_drawable.getIntrinsicWidth(),_drawable.getIntrinsicHeight());
        measure(0,0);
    }

    protected void onMeasure(int m, int m2) {
        setMeasuredDimension(_drawable.getIntrinsicWidth(), _drawable.getIntrinsicHeight());
    }

    protected void onDraw (Canvas canvas) {
        _drawable.draw(canvas);
    }
}



class GLViewGroup extends ViewGroup {

    private ClearGLSurfaceView mGLView;
    private ImageView mImageView;
    private int mX = 300;
    private int mY = 200;

    public GLViewGroup(Context context) {
        super(context);

        mGLView = new ClearGLSurfaceView(context);
        addView(mGLView);

        mImageView = new ImageView(context);
        addView(mImageView);

        setOnTouchListener(new OnTouchListener() {
            public boolean onTouch(View v, final MotionEvent event) {
                mX = (int)event.getX();
                mY = (int)event.getY();

                mImageView.layout(mX, mY, mX+mImageView.getMeasuredWidth(), mY+mImageView.getMeasuredHeight());

                mGLView.setColor(event);
                if (mGLView.getRenderMode()==GLSurfaceView.RENDERMODE_WHEN_DIRTY)
                    mGLView.requestRender();

                return true;
            }
        });

        measure(0, 0);
    }

    public void onResume() {
       mGLView.onResume();
    }

    public void onPause() {
        debug(0);
        mGLView.onPause();
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        mGLView.layout(l, t, r, b);
        mImageView.layout(mX, mY, mX+mImageView.getMeasuredWidth(), mY+mImageView.getMeasuredHeight());
    }
}


class ClearGLSurfaceView extends GLSurfaceView {
    public ClearGLSurfaceView(Context context) {
        super(context);
        mRenderer = new ClearRenderer();
        setRenderer(mRenderer);
        setRenderMode(RENDERMODE_WHEN_DIRTY);                       // <- remove this line and it works, but app is slow
        measure(0, 0);
    }

    public boolean onTouchEvent(final MotionEvent event) {
        setColor(event);
        return false;
    }

    public void setColor(final MotionEvent event) {
        queueEvent(new Runnable(){
            public void run() {
                mRenderer.setColor(event.getX() / getWidth(),
                        event.getY() / getHeight(), 1.0f);
            }});
    }

    private ClearRenderer mRenderer;
}



class ClearRenderer implements GLSurfaceView.Renderer {

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    }

    public void onSurfaceChanged(GL10 gl, int w, int h) {
        gl.glViewport(0, 0, w, h);
    }

    public void onDrawFrame(GL10 gl) {
        gl.glClearColor(mRed, mGreen, mBlue, 1.0f);
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    }

    public void setColor(float r, float g, float b) {
        mRed = r;
        mGreen = g;
        mBlue = b;
    }

    private float mRed   = 0.5f;
    private float mGreen = 0.5f;
    private float mBlue  = 0.5f;
}
...