如何用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(); } }
核心逻辑说明
- GLSurfaceView.Renderer:这是OpenGL渲染的核心接口,
onDrawFrame会被渲染线程反复调用,我们在这里设置清屏颜色并执行清屏操作,就能显示纯色背景。 - 颜色更新机制:通过定时任务(Kotlin用协程,Java用Handler)在主线程修改颜色变量,再调用
requestRender()触发GLSurfaceView重绘,从而实现颜色循环变化。 - 线程安全:用
volatile修饰颜色变量,确保渲染线程能及时读取到主线程更新的值,避免数据不一致问题。
内容的提问来源于stack exchange,提问作者Subbu
相关产品推荐
相关产品推荐

