You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Kotlin/Java驱动Android布局中的GLSurfaceView实现颜色轮播?

实现OpenGL SurfaceView颜色循环切换

没问题,我来帮你一步步搞定这个效果!要让GLSurfaceView循环切换屏幕颜色,核心是通过GLSurfaceView.Renderer控制渲染逻辑,再配合定时任务更新颜色值。下面分Kotlin和Java两种方案来讲解:

第一步:绑定布局中的GLSurfaceView

首先你需要给XML里的GLSurfaceView添加一个id,比如android:id="@+id/gl_surface_view",这样才能在Activity中获取到这个实例,后续所有操作都基于它。

Kotlin 实现方案

1. Activity 完整代码

import android.opengl.GLSurfaceView
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.*
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10

class ColorCycleActivity : AppCompatActivity() {
    private lateinit var glSurfaceView: GLSurfaceView
    // 用volatile保证颜色变量在主线程和渲染线程间的可见性
    @Volatile private var red: Float = 1f
    @Volatile private var green: Float = 0f
    @Volatile private var blue: Float = 0f
    // 颜色递增步长,数值越小颜色变化越平缓
    private val colorStep = 0.01f

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.your_activity_layout) // 替换成你的布局文件名

        // 获取GLSurfaceView实例
        glSurfaceView = findViewById(R.id.gl_surface_view)
        
        // 设置自定义渲染器
        glSurfaceView.setRenderer(object : GLSurfaceView.Renderer {
            override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
                // 初始化清屏颜色
                gl?.glClearColor(red, green, blue, 1f)
            }

            override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
                // 调整渲染视口适配屏幕尺寸
                gl?.glViewport(0, 0, width, height)
            }

            override fun onDrawFrame(gl: GL10?) {
                // 每次绘制时更新清屏颜色
                gl?.glClearColor(red, green, blue, 1f)
                // 执行清屏操作,显示当前颜色
                gl?.glClear(GL10.GL_COLOR_BUFFER_BIT)
            }
        })

        // 启动协程定时更新颜色
        CoroutineScope(Dispatchers.Main).launch {
            while (isActive) {
                // 循环递增颜色通道值(超过1f后重置为0f)
                red = (red + colorStep) % 1f
                green = (green + colorStep * 1.5f) % 1f // 不同步长让颜色变化更丰富
                blue = (blue + colorStep * 2f) % 1f
                
                // 触发GLSurfaceView重绘
                glSurfaceView.requestRender()
                
                // 每隔50ms更新一次,控制颜色变化速度
                delay(50)
            }
        }
    }

    // 必须重写这两个方法,保证GLSurfaceView生命周期正确
    override fun onResume() {
        super.onResume()
        glSurfaceView.onResume()
    }

    override fun onPause() {
        super.onPause()
        glSurfaceView.onPause()
    }
}

Java 实现方案

1. Activity 完整代码

import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;

import androidx.appcompat.app.AppCompatActivity;

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

public class ColorCycleActivity extends AppCompatActivity {
    private GLSurfaceView glSurfaceView;
    // 线程安全的颜色变量
    private volatile float red = 1f;
    private volatile float green = 0f;
    private volatile float blue = 0f;
    private final float colorStep = 0.01f;
    private Handler mainHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.your_activity_layout); // 替换成你的布局文件名

        glSurfaceView = findViewById(R.id.gl_surface_view);
        mainHandler = new Handler(Looper.getMainLooper());

        // 设置自定义渲染器
        glSurfaceView.setRenderer(new GLSurfaceView.Renderer() {
            @Override
            public void onSurfaceCreated(GL10 gl, EGLConfig config) {
                gl.glClearColor(red, green, blue, 1f);
            }

            @Override
            public void onSurfaceChanged(GL10 gl, int width, int height) {
                gl.glViewport(0, 0, width, height);
            }

            @Override
            public void onDrawFrame(GL10 gl) {
                gl.glClearColor(red, green, blue, 1f);
                gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
            }
        });

        // 用Handler定时更新颜色
        mainHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                // 循环更新颜色值
                red = (red + colorStep) % 1f;
                green = (green + colorStep * 1.5f) % 1f;
                blue = (blue + colorStep * 2f) % 1f;

                // 触发重绘
                glSurfaceView.requestRender();
                // 循环执行任务
                mainHandler.postDelayed(this, 50);
            }
        }, 50);
    }

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

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

核心逻辑说明

  1. GLSurfaceView.Renderer:这是OpenGL渲染的核心接口,onDrawFrame会被渲染线程反复调用,我们在这里设置清屏颜色并执行清屏操作,就能显示纯色背景。
  2. 颜色更新机制:通过定时任务(Kotlin用协程,Java用Handler)在主线程修改颜色变量,再调用requestRender()触发GLSurfaceView重绘,从而实现颜色循环变化。
  3. 线程安全:用volatile修饰颜色变量,确保渲染线程能及时读取到主线程更新的值,避免数据不一致问题。

内容的提问来源于stack exchange,提问作者Subbu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:16:05