一緒に書く習慣を身につけましょう!「ナゲッツデイリーニュープラン・4月アップデートチャレンジ」に参加して6日目です。クリックしてイベントの詳細をご覧ください。
SurfaceView
SurfaceView
ソースコードから継承されますがView
、内部実装SurfaceView
と他の実装View
には多くの違いがあります。SurfaceView
主な機能は、ビュー構造に埋め込まれた直接描画サーフェスを提供することです。これにより、実際に描画機能が実行されSurface
ます。したがって、SurfaceView
ホストウィンドウとは別のものです。通常の状況では、ウィンドウView
は同じウィンドウを共有しますが、1つWindow
にWindow
も対応しSurface
、すべてView
同じウィンドウを共有しSurface
ます。したがって、これはSurfaceView
独立しています。Surface
これは、互いに干渉することなく、ホストウィンドウの描画から分離されていることと同じです。
違い
違い | SurfaceView | 意見 |
---|---|---|
描く | 構造はビューにありますが、描画面は独立しています。内部には、描画操作用の独自のキャンバスがあります | ホストウィンドウと同じ描画面を共有します |
リフレッシュ | ウィンドウの更新では、ホストウィンドウを再描画する必要はありません | 子要素または部分的な更新により、ビュー構造全体が再描画されます |
スレッド | スレッドは独立しており、インターフェイスを使用したメインスレッドの頻繁な更新には影響しません。 | メインUIスレッドで使用 |
操作する | 下位バージョンは、平行移動、ズーム、回転などのアニメーションをサポートしておらず、Viewプロパティコントロールを備えていません。 | 正常に動作できます |
リフレッシュ | 制御可能なリフレッシュレート、ダブルキャッシュメカニズム | メインスレッドの更新のみを更新する |
ダブルバッファーメカニズム
SurfaceView
ビデオストリームを画像データ表示のフレームに解析します。たとえば、ある画像フレームが表示された後、次の画像フレームを待つことが時間内に解析されない場合があります。この場合、画像は滑らかになりません。この状況は、ダブルバッファリングを使用することで回避できます。ダブルバッファリングとは、2つのスレッドが交互にビデオストリームの画像データを解析し、解析とレンダリングの操作を交互に実行して、ビデオストリームをスムーズに再生できるようにすることを意味します。
SurfaceHolder
SurfaceView
ダブルバッファリングメカニズムは、実際にはより多くのシステムメモリを消費します。したがって、表示されていない場合は、メモリのオーバーヘッドを減らすためSurfaceView
に破棄されます。SurfaceHolder
したがって、ステータスを監視するSurfaceHolder
方法があります。addCallback
SurfaceHolder
- void surfaceCreated(@NonNull SurfaceHolderholder);コールバックを作成します
- void surfaceChanged(@NonNull SurfaceHolderホルダー、@ PixelFormat.Format int format、@ IntRange(from = 0)int width、@IntRange(from = 0)int height); 修改回调
- void surfaceDestroyed(@NonNull SurfaceHolderholder);コールバックを破棄します
使用する
カスタム継承SurfaceView
を使用すると、描画される内容をカスタマイズできます。作成がSurfaceHolder
成功したら、surfaceCreated
コールバックでlockCanvas
取得したキャンバスを呼び出してSurfaceHolder
ロックし、コンテンツを描画します。描画が終了したら、unlockCanvasAndPost
releaseを呼び出してキャンバスの変更情報を送信し、新しいデータをキャンバスに表示できるようにします。
public class SurfaceViewTest extends SurfaceView implements SurfaceHolder.Callback{
private SurfaceHolder mSurfaceHolder;
private Canvas mCanvas;
private Paint paint;
public SurfaceViewTest(Context context) {
this(context,null,0);
}
public SurfaceViewTest(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public SurfaceViewTest(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mSurfaceHolder = getHolder(); // 初始化
mSurfaceHolder.addCallback(this);
setFocusable(true);
setFocusableInTouchMode(true);
this.setKeepScreenOn(true);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.RED);
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.STROKE);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// 创建成功后就能通过线程绘制自定义内容
new Thread(new Runnable() {
@Override
public void run() {
draw();
}
}).start();
}
private void draw() {
try {
mCanvas = mSurfaceHolder.lockCanvas();
mCanvas.drawCircle(500,500,300,paint);
mCanvas.drawCircle(100,100,20,paint);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (mCanvas != null)
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {}
}
复制代码