精华内容
下载资源
问答
  • SurfaceView

    2018-06-07 14:03:53
    SurfaceView
    SurfaceView
    展开全文
  • surfaceView

    2015-12-11 16:39:46
    一个简单的surfaceview绘制,内赠送一个下载进度的监听view
  • Surfaceview

    2019-07-09 20:47:15
    SurfaceView SurfaceView和View的区别: View 主要适用于主动更新的情况,而 surfaceView 主要适用于被动更新,例如频繁的刷新。 View 在主线程中对画面进行刷新,而 surfaceView 通常会通过一个子线程来进行页面的...

    SurfaceView

    SurfaceView和View的区别:
    View 主要适用于主动更新的情况,而 surfaceView 主要适用于被动更新,例如频繁的刷新。
    View 在主线程中对画面进行刷新,而 surfaceView 通常会通过一个子线程来进行页面的刷新
    View 在绘图时没有使用双缓冲机制,而 surfaceView 在底层实现机制上就已经实现了双缓冲机制。
    总结就是,如果你的自定义 View 需要频繁刷新,或者刷新时数据处理量很大,考虑用 SurfaceView 来替代 View。

    双缓冲:

    在这里插入图片描述

    surfaceview如何播放视频+surfaceview发送弹幕

    在这里插入图片描述

    实现代码

    package com.example.day05_test;
    
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.PixelFormat;
    import android.graphics.PorterDuff;
    import android.media.MediaPlayer;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    
    import java.io.IOException;
    import java.util.ArrayList;
    
    public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
        SurfaceView vido;
        SurfaceView danmu;
        SurfaceHolder holder_void;
        SurfaceHolder holder_danmu;
        MediaPlayer mediaPlayer = new MediaPlayer();
        EditText et;
        Button bt;
        int y = 0;
        ArrayList<Barrage> list = new ArrayList<>();
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mediaPlayer = new MediaPlayer();
            bt = findViewById(R.id.bt);
            et = findViewById(R.id.et);
            //视频
            vido =findViewById(R.id.vido);
            holder_void = vido.getHolder();
            holder_void.addCallback(this);
            //弹幕
            danmu =findViewById(R.id.danmu);
            holder_danmu = danmu.getHolder();
            holder_danmu.addCallback(this);
            //变成半透明
            danmu.setZOrderOnTop(true);
            holder_danmu.setFormat(PixelFormat.TRANSLUCENT);
            //自定义方法
            initMedia();
            //按钮点击事件
            bt.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String text = et.getText().toString();
                    int height = danmu.getHeight();
                    y = (int) (Math.random()*height);
                    Barrage barrage = new Barrage(0, y, text);
                    list.add(barrage);
                }
            });
        }
    
        private void initMedia() {
            mediaPlayer.reset();
            try {
                mediaPlayer.setDataSource("http://wvideo.spriteapp.cn/video/2019/0708/5d232436d1fc5_wpd.mp4");
                mediaPlayer.prepareAsync();
                mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        mediaPlayer.start();
                    }
                });
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
                    if (holder == holder_void){
                        mediaPlayer.setDisplay(holder);
                    }else {
                        new MyThread().start();
                    }
        }
    
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
    
        }
        class MyThread extends Thread{
            @Override
            public void run() {
                Paint paint = new Paint();
                paint.setTextSize(60);
                while (true){
                    Canvas canvas = holder_danmu.lockCanvas();
                    if (canvas == null){
                        break;
                    }
                    canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
                    for (int i = 0; i < list.size(); i++) {
                        int a = (int) (Math.random()*255);
                        int b = (int) (Math.random()*255);
                        int c = (int) (Math.random()*255);
                        paint.setColor(Color.rgb(a,b,c));
                        int x = list.get(i).getX();
                        list.get(i).setX(x+=10);
                        canvas.drawText(list.get(i).getText(),list.get(i).getX(),list.get(i).getY(),paint);
                    }
                    holder_danmu.unlockCanvasAndPost(canvas);
                }
            }
        }
    }
    
    

    布局代码

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity" android:orientation="vertical">
        <FrameLayout
            android:layout_weight="8"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <SurfaceView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/vido"
                />
            <SurfaceView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/danmu"
                />
        </FrameLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <EditText
                android:id="@+id/et"
                android:layout_width="0dp"
                android:layout_height="wrap_content" android:layout_weight="8"/>
            <Button
                android:layout_width="0dp"
                android:layout_height="wrap_content" android:layout_weight="2"
                android:text="发送"
                android:id="@+id/bt"
                />
        </LinearLayout>
    </LinearLayout>
    
    展开全文
  • surfaceview

    2019-04-01 20:00:28
    View,SurfaceView,GLSurfaceView有什么区别? 1)View View类是Android的一个非常重要的超类,它是Android里所有与用户交互的控件的父类,包括Widget类的交互UI控件(按钮、文本框等)和ViewGroup类布局控件。...

    View,SurfaceView,GLSurfaceView有什么区别?

    1)View

    View类是Android的一个非常重要的超类,它是Android里所有与用户交互的控件的父类,包括Widget类的交互UI控件(按钮、文本框等)和ViewGroup类布局控件。SurfaceView继承自View,GLSurfaceView继承自SurfaceView。
    2)SurfaceView

    2.1SurfaceView概述
           普通的Android控件,例如TextView、Button和CheckBox等,它们都是将自己的UI绘制在宿主窗口的绘图表面之上,这意味着它们的 UI是在应用程序的主线程中进行绘制的。由于应用程序的主线程除了要绘制 UI之外,还需要及时地响应用户输入,否则的话,系统就会认为应用程序没有响应了,因此就会弹出一个 ANR对话框出来。对于一些游戏画面,或者摄像头预览、视频播放来说,它们的 UI都比较复杂,而且要求能够进行高效的绘制,因此,它们的 UI就不适合在应用程序的主线程中进行绘制。这时候就必须要给那些需要复杂而高效 UI的视图生成一个独立的绘制这些视图的UI

    2.2 SurfaceView 的大致实现原理
            Android应用程序窗口是通过 SurfaceFlinger服务来绘制自己的UI的。一般来说,每一个窗口在 SurfaceFlinger服务中都对应有一个 Layer,用来描述它的绘图表面。对于那些具有 SurfaceView的窗口来说,每一个 SurfaceView在SurfaceFlinger服务中还对应有一个独立的Layer或者LayerBuffer,用来单独描述它的绘图表面,以区别于它的宿主窗口的绘图表面。

              无论是LayerBuffer,还是Layer,它们都是以LayerBase为基类的,也就是说,SurfaceFlinger服务把所有的LayerBuffer和Layer都抽象为LayerBase,因此就可以用统一的流程来绘制和合成它们的UI。

              我们假设在一个Activity窗口的视图结构中,除了有一个DecorView顶层视图之外,还有两个TextView控件,以及一个SurfaceView视图,这样该Activity窗口在SurfaceFlinger服务中就对应有两个Layer或者一个Layer的在SurfaceFlinger服务中还对应有一个独立的Layer或者LayerBuffer,用来单独描述它的绘图表面,以区别于它的宿主窗口的绘图表面。无论是LayerBuffer,还是Layer,它们都是以LayerBase为基类的,也就是说,SurfaceFlinger服务把所有的LayerBuffer和Layer都抽象为LayerBase,因此就可以用统一的流程来绘制和合成它们的UI。
    我们假设在一个Activity窗口的视图结构中,除了有一个DecorView顶层视图之外,还有两个TextView控件,以及一个SurfaceView视图,这样该Activity窗口在SurfaceFlinger服务中就对应有两个Layer或者一个Layer的一个LayerBuffer,如图所示:

     

     


    在图中,Activity窗口的顶层视图 DecorView及其两个 TextView控件的 UI都是绘制在 SurfaceFlinger服务中的同一个 Layer上面的,而 SurfaceView的 UI是绘制在 SurfaceFlinger服务中的另外一个 Layer或者 LayerBuffer上的。

    注意,用来描述 SurfaceView的 Layer或者 LayerBuffer的 Z轴位置是小于用来其宿主 Activity窗口的 Layer

    的Z轴位置的,但是前者会在后者的上面挖一个“洞”出来,以便它的UI可以对用户可见。实际上,SurfaceView在其宿主Activity窗口上所挖的“洞”只不过是在其宿主Activity窗口上设置了一块透明区域。


    2.3SurfaceView的简单使用
    a.获取到SurfaceView对应的SurfaceHolder,给SurfaceHolder添加一个SurfaceHolder.callback对象。
    b.创建渲染线程对象
    c.在子线程中开始在Surface上面绘制图形,因为SurfaceView没有对我们暴露Surface,而只是暴露了Surface的包装器SurfaceHolder,所以使用SurfaceHolder的lockCanvas()获取Surface上面指定区域的Canvas,在该Canvas上绘制图形,绘制结束后,使用SurfaceHolder的unlockCanvasAndPost()方法解锁Canvas,并且让UI线程把Surface上面的东西绘制到View的Canvas上面。示例代码如下:


    1.publicclassGameUIextendsSurfaceViewimplementsSurfaceHolder.Callback{
    2.privateSurfaceHolderholder;
    3.privateRenderThreadrenderThread;
    4.privatebooleanisDraw=false;//控制绘制的开关
    5.publicGameUI(Contextcontext){
    6.super(context);holder=this.getHolder();
    7.holder.addCallback(this);
    8.renderThread=newRenderThread();
    9.}
    10.@OverridepublicvoidsurfaceChanged(SurfaceHolderholder,intformat,intwidth,intheight)
    11.{}
    12.@OverridepublicvoidsurfaceCreated(SurfaceHolderholder){
    13.isDraw=true;
    14.renderThread.start();
    15.}
    16.@OverridepublicvoidsurfaceDestroyed(SurfaceHolderholder){
    230

     

     

    17.isDraw=false;
    18.}
    19./**
    20.*绘制界面的线程
    21.*
    22.*@authorAdministrator23.*
    24.*/
    25.privateclassRenderThreadextendsThread{
    26.@Overridepublicvoidrun(){
    27.//不停绘制界面
    28.while(isDraw){
    29.drawUI();
    30.}
    31.super.run();
    32.}
    33.}
    34./**
    35.*界面绘制
    36.*/
    37.publicvoiddrawUI(){
    38.Canvascanvas=holder.lockCanvas();
    39.try{
    40.drawCanvas(canvas);
    41.}catch(Exceptione){
    42.e.printStackTrace();
    43.}finally{
    44.holder.unlockCanvasAndPost(canvas);
    45.}
    46.}
    47.privatevoiddrawCanvas(Canvascanvas){
    48.//在canvas上绘制需要的图形
    49.}
    50.}
    3) 
    GLSurfaceView

    3.1GLSurfaceView概述
    GLSurfaceView是一个视图,继承至 SurfaceView,它内嵌的 surface专门负责 OpenGL渲染。GLSurfaceView提供了下列特性:

     

    1>管理一个 surface,这个 surface就是一块特殊的内存,能直接排版到 Android的视图 view上。
    2>管理一个 EGL display,它能让 opengl把内容渲染到上述的 surface上。
    3>用户自定义渲染器(render)。
    4>让渲染器在独立的线程里运作,和 UI线程分离。
    5>支持按需渲染(on-demand)和连续渲染(continuous)。

    6>一些可选工具,如调试。

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,926
精华内容 3,970
关键字:

surfaceview