스레드 내에서 SurfaceView에 도형을 그리려고하지만 아무 것도 화면에 렌더링되지 않습니다. 저는 같은 문제를 가진 사람들이 비슷한 질문을 한 적이 있지만 그 답이 하나도 없기 때문에 어떤 경우에 다른 원인을 제시하는 해결책을 찾지 못했습니다.SurfaceView가 비어 있고 아무 것도 렌더링되지 않습니다.
문제를 설명하기 위해 간단한 코드 버전을 만들었습니다. 렌더링은 SurfaceView에서 파생 된 사용자 정의보기를 구현하는 RenderingTestView 클래스에 의해 처리됩니다.
package com.example.renderingtest.app;
import android.content.Context;
import android.graphics.*;
import android.os.Build;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class RenderingTestView extends SurfaceView {
private SurfaceHolder holder;
private Paint paint;
private boolean surfaceCreated = false;
private Thread videoThread;
public RenderingTestView(Context context) {
super(context);
init_view(context);
}
public RenderingTestView(Context context, AttributeSet attrs) {
super(context, attrs);
init_view(context);
}
public RenderingTestView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init_view(context);
}
private void init_view(Context context)
{
if (Build.VERSION.SDK_INT >= 11)
setLayerType(android.view.View.LAYER_TYPE_SOFTWARE, null);
paint = new Paint();
paint.setColor(Color.RED);
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
surfaceCreated = true;
videoThread = new Thread(videoRunnable);
videoThread.start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// do nothing
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
surfaceCreated = false;
}
});
}
private Runnable videoRunnable = new Runnable() {
@Override
public void run() {
Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
while (true) {
if (!surfaceCreated || !holder.getSurface().isValid())
continue;
Canvas c = holder.lockCanvas(null);
try {
synchronized (holder) {
if (c != null)
Draw(c);
}
}
finally {
if (c != null)
holder.unlockCanvasAndPost(c);
}
}
}
};
protected void Draw(Canvas canvas)
{
canvas.drawCircle(0, 0, 100, paint);
}
}
이 Draw()
내부에 중단 점을 배치 성공적으로 호출되고 있다고 확인 : 렌더링 스레드의 Runnable 내부 RenderingTestView로 구현됩니다.
은 레이아웃 파일은 다음과 같다 :
@Override
public void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Draw(canvas);
}
을 ... 사실에서 원하는 출력을 생성 않습니다 init_view()
내부 setWillNotDraw(false)
전화 :하지만,
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="com.example.renderingtest.app.RenderingTest" android:background="#000000">
<com.example.renderingtest.app.RenderingTest
android:id="@+id/renderingTestView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" android:layout_alignParentTop="true"/>
</RelativeLayout>
이 같은 RenderingTestView
에 onDraw()
재정의 onDraw()
에 대한 호출을 생성하기 위해 invalidate()를 기다리지 않고 Runnable 내부에서 렌더링하려고합니다.
당신이하고있는 일과 왜 잘못되었는지를 묘사하기가 어렵습니다. SurfaceView는 다른 뷰와 다르다는 것을 이해하십시오 - View 파트와 Surface 파트가 있습니다. 보기 부분은 레이아웃을위한 투명한 자리 표시 자이므로 무시해야합니다. Surface는 SurfaceHolder API로 Z 순서를 변경하지 않는 한 모든 UI 요소 뒤에 그려지는 완전히 별개의 레이어입니다. 레이아웃을 확인하고보기 부분을 불투명 한 색상으로 지우지 않았는지 확인하십시오. – fadden
내가하고있는 것은 셰이프를 SurfaceView의 캔버스에 렌더링하는 것이다. 문제는 제가 게시 한 정확한 코드가 사실 캔버스 위에 아무것도 그리지 않는다는 것입니다. 어쨌든, 나는 마침내 원인을 발견하고 대답을 게시 할 것입니다. –