SurfaceView

一.使用SurfaceView播放视频

1.布局

<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">
   <SurfaceView
       android:layout_width="match_parent"
       android:layout_height="400dp"
       android:id="@+id/surfaceview"></SurfaceView>
    <SeekBar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="@style/Widget.AppCompat.ProgressBar.Horizontal"
        android:id="@+id/progressbar"></SeekBar>


</LinearLayout>

2.MainActivity代码

public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
    private SurfaceView surfaceview;
    private SeekBar progressbar;
    MediaPlayer mediaPlayer = new MediaPlayer();
    SurfaceHolder surfaceHolder;
    Timer timer = new Timer();
    String video;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        surfaceview = (SurfaceView) findViewById(R.id.surfaceview);
        progressbar = (SeekBar) findViewById(R.id.progressbar);
        surfaceHolder = surfaceview.getHolder();
        surfaceHolder.addCallback(this);

        Intent intent = getIntent();
//        video = intent.getStringExtra("video");
        Toast.makeText(this,""+video,Toast.LENGTH_SHORT).show();
        try {
            initplayer();
        } catch (IOException e) {
            e.printStackTrace();
        }
        progressbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                if (b){
                    mediaPlayer.seekTo(seekBar.getProgress());
                }

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

    }

    private void initplayer() throws IOException {
        if (mediaPlayer!=null){
            mediaPlayer.reset();
            mediaPlayer.setDataSource("http://tvideo.spriteapp.cn/video/2019/0910/5d7691e370b3c_wpd.mp4");
            mediaPlayer.setDataSource(video);
            mediaPlayer.prepareAsync();
            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
               @Override
               public void onPrepared(MediaPlayer mediaPlayer) {
                   mediaPlayer.start();
                   int videoWidth = mediaPlayer.getVideoWidth();
               }
           });

            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    int duration = mediaPlayer.getDuration();
                    int currentPosition = mediaPlayer.getCurrentPosition();
                    int i = currentPosition * 100 / duration;
                    progressbar.setProgress(i);
                }
            },0,1000);

        }

    }

    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        Log.d("zyj", "创建了: ");
        mediaPlayer.setDisplay(surfaceHolder);
    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
        Log.d("zyj", "改变了: ");

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        Log.d("zyj", "销毁了: ");
        if (mediaPlayer!=null){
            mediaPlayer.release();
            mediaPlayer=null;
        }
        if (timer!=null){
            timer.cancel();
        }

    }
}

二.使用SurfaceView绘制各种图形

1.绘制各种图形

public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
    private SurfaceView surfaceview;
    private SurfaceHolder surfaceHolder;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        surfaceview = (SurfaceView) findViewById(R.id.surfaceview);
        surfaceHolder = surfaceview.getHolder();
        surfaceHolder.addCallback(this);
    }

    //创建
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        //TODO:1.画笔
        Paint paint = new Paint();
        //TODO:2.设置笔的颜色
        paint.setColor(Color.BLUE);
        //设置画笔样式,fill是实心,stoke是空心,fill_or_stoke:同时实心与空心
//        paint.setStyle(Paint.Style.FILL);
//        paint.getTextSize(float textsize)//设置绘制文字的字号大小
//        paint.setAntiAlias(true);//抗锯齿
        //TODO:3.设置线条宽度
        paint.setStrokeWidth(20);

        TODO:3.画布
        Canvas canvas = surfaceHolder.lockCanvas();//锁定画布
        canvas.drawColor(Color.WHITE);//设置画布颜色
        //画一条线
        canvas.drawLine(0,0,500,500,paint);
        //画一个点
        canvas.drawPoint(300,300,paint);
        //画一个圆形(oval是椭圆)
        canvas.drawOval(200,200,400,400,paint);
        //画文字
        /**
         * 参数1:要从第几个文字开始绘制
         * 参数2:要绘制到第几个文字
         * 参数3:文本的X轴的开始位置
         * 参数4:文本的Y轴的结束位置
         * 参数5 画笔对象
         */
        canvas.drawText("开始写字了",50,50,paint);
        /**
         * 参数1:路径
         * 参数2:距离路径开始位置的偏移量
         * 参数3:距离路径上下的偏移量
         * 参数4:画笔对象
         */
//        canvas.drawTextOnPath("123456789",path,0,-50,paint);

        //画矩形
        /**
         * 参数1:float left
         * 参数2:float top
         * 参数3:float right
         * 参数4:float buttom
         */
        canvas.drawRect(100,100,200,200,paint);
        //画圆角矩形
        RectF rectF = new RectF(80, 260, 200, 300);//设置个新的长方形
        canvas.drawRoundRect(rectF,20,5,paint);//第二个参数是X半径,第三个参数是Y半径

        //画扇形
        canvas.drawArc(500,500,700,700,20,180,true,paint);
        surfaceHolder.unlockCanvasAndPost(canvas);//解锁画布
    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {

    }
}

三.播放音乐的时候,滚动歌词

1. xml布局

<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=".MusicActivity"
    android:orientation="vertical">
    <SurfaceView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/surfaceview3"></SurfaceView>

</LinearLayout>

2.MainActivity中代码

public class MusicActivity extends AppCompatActivity implements SurfaceHolder.Callback {
    private Timer timer = new Timer();
    private SurfaceView surfaceview3;
    ArrayList<Music>list = new ArrayList<>();
    private MediaPlayer mediaPlayer = new MediaPlayer();
    SurfaceHolder surfaceHolder;
    int position;//正在显示的歌词的下标

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_music);
        surfaceview3 = (SurfaceView) findViewById(R.id.surfaceview3);
        surfaceHolder = surfaceview3.getHolder();
        surfaceHolder.addCallback(this);

        if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
            requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE},100);
        }
        try {
            initCi();   //解析歌词
            initPlayer(); //播放音乐
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void initPlayer() throws IOException {
        if (mediaPlayer!=null){
            mediaPlayer.reset();
            mediaPlayer.setDataSource("/sdcard/凤凰传奇 - 最炫民族风(Live).mp3");
            mediaPlayer.prepareAsync();
            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(final MediaPlayer mediaPlayer) {
                    mediaPlayer.start();
                    timer.schedule(new TimerTask() {
                        @Override
                        public void run() {
                             if (list.size()>0&& position+1<list.size()){
                                 int currentPosition = mediaPlayer.getCurrentPosition();
                                 if (currentPosition>=list.get(position+1).getStart_time()) {
                                     position++;
                                 }
                             }
                        }
                    },0,100);
                }
            });
        }
    }

    private void initCi() throws IOException {
        //TODO 1:读取SD卡的歌词 json串
        FileInputStream fileInputStream = new FileInputStream("/sdcard/最炫民族风");
        StringBuffer stringBuffer = new StringBuffer();
        byte[] bytes = new byte[1024];
        int len=0;
        while((len=fileInputStream.read(bytes))!=-1){
            stringBuffer.append(new String(bytes,0,len));
        }
        //TODO 2:解析json串获得整首歌的歌词
        Gson gson = new Gson();
        Bean bean = gson.fromJson(stringBuffer.toString(), Bean.class);
        String lyric = bean.getLrc().getLyric();
        Log.d("zjy", "initCi: "+lyric);
        //TODO 3:按照\n进行切割得到每句歌词
        String[] split = lyric.split("\n");
        for (int i = 1; i < split.length; i++) {
            String replace = split[i].replace("[", "")
                    .replaceFirst(":","@")//只替换第一个
                    .replace(".","@")
                    .replace("]","@");

            Log.d("zjy", "initCi: "+replace);
            String[] split1 = replace.split("@");
            int  start_time= Integer.parseInt(split1[0])*60*1000+Integer.parseInt(split1[1])*1000+Integer.parseInt(split1[2]);
            if (split1.length>=4){
                list.add(new Music(split1[3],start_time));
            }
        }
        //TODO 4:打印集合数据
        for (Music music:list){
            Log.d("zjy", "initCi: "+music);
        }

    }

    @Override
    public void surfaceCreated(final SurfaceHolder surfaceHolder) {
          new Thread(new Runnable() {
              @Override
              public void run() {
                  Paint paint = new Paint();
                  paint.setColor(Color.RED);
                  paint.setTextSize(40);
                  while (true){
                      Canvas canvas = surfaceHolder.lockCanvas();
                      canvas.drawColor(Color.WHITE);
                      canvas.drawText(list.get(position).getText(),200,300,paint);
                      surfaceHolder.unlockCanvasAndPost(canvas);
                  }
              }
          }).start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {

    }
}

3.Bean类(歌词类)

package com.example.app2.bean;

public class Bean {

    /**
     * sgc : false
     * sfy : false
     * qfy : false
     * lyricUser : {"id":29418062,"status":0,"demand":0,"userid":12907497,"nickname":"Simfre","uptime":1441503572343}
     * lrc : {"version":5,"lyric":"[by:简单de频率]\n[00:00.000] 作曲 : 张超\n[00:01.000] 作词 : 张超\n[00:22.600]苍茫的天涯是我的爱\n[00:26.280]绵绵的青山脚下花正开\n[00:30.130]什么样的节奏是最呀最摇摆\n[00:33.880]什么样的歌声才是最开怀\n[00:37.750]弯弯的河水从天上来\n[00:41.310]流向那万紫千红一片海\n[00:45.330]火辣辣的歌谣是我们的期待\n[00:48.880]一路边走边唱才是最自在\n[00:52.630]我们要唱就要唱得最痛快\n[00:56.610]你是我天边最美的云彩\n[01:00.280]让我用心把你留下来(留下来)\n[01:04.340]悠悠的唱着最炫的民族风\n[01:07.840]让爱卷走所有的尘埃\n[01:10.470](我知道)你是我心中最美的云彩\n[01:15.380]斟满美酒让你留下来(留下来)\n[01:19.380]永远都唱着最炫的民族风\n[01:22.760]是整片天空最美的姿态\n[01:26.700]哟啦啦呵啦呗\n[01:28.520]伊啦嗦啦呵啦呗呀\n[01:30.700]我听见你心中动人的天籁\n[01:34.260]登上天外云霄的舞台\n[01:37.530]\n[01:53.250]苍茫的天涯是我的爱\n[01:56.940]绵绵的青山脚下花正开\n[02:00.820]什么样的节奏是最呀最摇摆\n[02:04.570]什么样的歌声才是最开怀\n[02:08.440]弯弯的河水从天上来\n[02:12.000]流向那万紫千红一片海\n[02:15.810]火辣辣的歌谣是我们的期待\n[02:19.620]一路边走边唱才是最自在\n[02:23.310]我们要唱就要唱得最痛快\n[02:27.220]你是我天边最美的云彩\n[02:30.920]让我用心把你留下来(留下来)\n[02:34.920]悠悠的唱着最炫的民族风\n[02:38.410]让爱卷走所有的尘埃\n[02:41.410](我知道)你是我心中最美的云彩\n[02:46.210]斟满美酒让你留下来(留下来)\n[02:50.140]永远都唱着最炫的民族风\n[02:53.460]是整片天空最美的姿态\n[02:57.810]\n[03:18.290]你是我天边最美的云彩\n[03:21.910]让我用心把你留下来(留下来)\n[03:26.030]悠悠的唱着最炫的民族风\n[03:29.510]让爱卷走所有的尘埃\n[03:32.260](我知道)你是我心中最美的云彩\n[03:37.010]斟满美酒让你留下来(留下来)\n[03:41.070]永远都唱着最炫的民族风\n[03:44.570]是整片天空最美的姿态\n[03:48.990]\n[03:50.300]我听见你心中那动人的天籁\n[03:53.990]就忽如一夜春风袭来满面桃花开\n[03:57.860]我忍不住去采 我忍不住去摘\n[04:01.620]我敞开胸怀为你等待\n[04:04.340]\n[04:05.840]你是我天边最美的云彩\n[04:09.280]让我用心把你留下来\n[04:13.010]悠悠的唱着最炫的民族风\n[04:16.750]让爱卷走所有的尘埃\n[04:19.500](我知道)你是我心中最美的云彩\n[04:24.250]斟满美酒让你留下来(留下来)\n[04:28.380]永远都唱着最炫的民族风\n[04:31.750]是整片天空最美的姿态\n[04:36.190]\n"}
     * klyric : {"version":0,"lyric":null}
     * tlyric : {"version":0,"lyric":null}
     * code : 200
     */

    private boolean sgc;
    private boolean sfy;
    private boolean qfy;
    private LyricUserBean lyricUser;
    private LrcBean lrc;
    private KlyricBean klyric;
    private TlyricBean tlyric;
    private int code;

    public boolean isSgc() {
        return sgc;
    }

    public void setSgc(boolean sgc) {
        this.sgc = sgc;
    }

    public boolean isSfy() {
        return sfy;
    }

    public void setSfy(boolean sfy) {
        this.sfy = sfy;
    }

    public boolean isQfy() {
        return qfy;
    }

    public void setQfy(boolean qfy) {
        this.qfy = qfy;
    }

    public LyricUserBean getLyricUser() {
        return lyricUser;
    }

    public void setLyricUser(LyricUserBean lyricUser) {
        this.lyricUser = lyricUser;
    }

    public LrcBean getLrc() {
        return lrc;
    }

    public void setLrc(LrcBean lrc) {
        this.lrc = lrc;
    }

    public KlyricBean getKlyric() {
        return klyric;
    }

    public void setKlyric(KlyricBean klyric) {
        this.klyric = klyric;
    }

    public TlyricBean getTlyric() {
        return tlyric;
    }

    public void setTlyric(TlyricBean tlyric) {
        this.tlyric = tlyric;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public static class LyricUserBean {
        /**
         * id : 29418062
         * status : 0
         * demand : 0
         * userid : 12907497
         * nickname : Simfre
         * uptime : 1441503572343
         */

        private int id;
        private int status;
        private int demand;
        private int userid;
        private String nickname;
        private long uptime;

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public int getStatus() {
            return status;
        }

        public void setStatus(int status) {
            this.status = status;
        }

        public int getDemand() {
            return demand;
        }

        public void setDemand(int demand) {
            this.demand = demand;
        }

        public int getUserid() {
            return userid;
        }

        public void setUserid(int userid) {
            this.userid = userid;
        }

        public String getNickname() {
            return nickname;
        }

        public void setNickname(String nickname) {
            this.nickname = nickname;
        }

        public long getUptime() {
            return uptime;
        }

        public void setUptime(long uptime) {
            this.uptime = uptime;
        }
    }

    public static class LrcBean {
        /**
         * version : 5
         * lyric : [by:简单de频率]
         [00:00.000] 作曲 : 张超
         [00:01.000] 作词 : 张超
         [00:22.600]苍茫的天涯是我的爱
         [00:26.280]绵绵的青山脚下花正开
         [00:30.130]什么样的节奏是最呀最摇摆
         [00:33.880]什么样的歌声才是最开怀
         [00:37.750]弯弯的河水从天上来
         [00:41.310]流向那万紫千红一片海
         [00:45.330]火辣辣的歌谣是我们的期待
         [00:48.880]一路边走边唱才是最自在
         [00:52.630]我们要唱就要唱得最痛快
         [00:56.610]你是我天边最美的云彩
         [01:00.280]让我用心把你留下来(留下来)
         [01:04.340]悠悠的唱着最炫的民族风
         [01:07.840]让爱卷走所有的尘埃
         [01:10.470](我知道)你是我心中最美的云彩
         [01:15.380]斟满美酒让你留下来(留下来)
         [01:19.380]永远都唱着最炫的民族风
         [01:22.760]是整片天空最美的姿态
         [01:26.700]哟啦啦呵啦呗
         [01:28.520]伊啦嗦啦呵啦呗呀
         [01:30.700]我听见你心中动人的天籁
         [01:34.260]登上天外云霄的舞台
         [01:37.530]
         [01:53.250]苍茫的天涯是我的爱
         [01:56.940]绵绵的青山脚下花正开
         [02:00.820]什么样的节奏是最呀最摇摆
         [02:04.570]什么样的歌声才是最开怀
         [02:08.440]弯弯的河水从天上来
         [02:12.000]流向那万紫千红一片海
         [02:15.810]火辣辣的歌谣是我们的期待
         [02:19.620]一路边走边唱才是最自在
         [02:23.310]我们要唱就要唱得最痛快
         [02:27.220]你是我天边最美的云彩
         [02:30.920]让我用心把你留下来(留下来)
         [02:34.920]悠悠的唱着最炫的民族风
         [02:38.410]让爱卷走所有的尘埃
         [02:41.410](我知道)你是我心中最美的云彩
         [02:46.210]斟满美酒让你留下来(留下来)
         [02:50.140]永远都唱着最炫的民族风
         [02:53.460]是整片天空最美的姿态
         [02:57.810]
         [03:18.290]你是我天边最美的云彩
         [03:21.910]让我用心把你留下来(留下来)
         [03:26.030]悠悠的唱着最炫的民族风
         [03:29.510]让爱卷走所有的尘埃
         [03:32.260](我知道)你是我心中最美的云彩
         [03:37.010]斟满美酒让你留下来(留下来)
         [03:41.070]永远都唱着最炫的民族风
         [03:44.570]是整片天空最美的姿态
         [03:48.990]
         [03:50.300]我听见你心中那动人的天籁
         [03:53.990]就忽如一夜春风袭来满面桃花开
         [03:57.860]我忍不住去采 我忍不住去摘
         [04:01.620]我敞开胸怀为你等待
         [04:04.340]
         [04:05.840]你是我天边最美的云彩
         [04:09.280]让我用心把你留下来
         [04:13.010]悠悠的唱着最炫的民族风
         [04:16.750]让爱卷走所有的尘埃
         [04:19.500](我知道)你是我心中最美的云彩
         [04:24.250]斟满美酒让你留下来(留下来)
         [04:28.380]永远都唱着最炫的民族风
         [04:31.750]是整片天空最美的姿态
         [04:36.190]

         */

        private int version;
        private String lyric;

        public int getVersion() {
            return version;
        }

        public void setVersion(int version) {
            this.version = version;
        }

        public String getLyric() {
            return lyric;
        }

        public void setLyric(String lyric) {
            this.lyric = lyric;
        }
    }

    public static class KlyricBean {
        /**
         * version : 0
         * lyric : null
         */

        private int version;
        private Object lyric;

        public int getVersion() {
            return version;
        }

        public void setVersion(int version) {
            this.version = version;
        }

        public Object getLyric() {
            return lyric;
        }

        public void setLyric(Object lyric) {
            this.lyric = lyric;
        }
    }

    public static class TlyricBean {
        /**
         * version : 0
         * lyric : null
         */

        private int version;
        private Object lyric;

        public int getVersion() {
            return version;
        }

        public void setVersion(int version) {
            this.version = version;
        }

        public Object getLyric() {
            return lyric;
        }

        public void setLyric(Object lyric) {
            this.lyric = lyric;
        }
    }
}

4.实体类

package com.example.app2.entity;

public class Music {
    private String text;
    private long start_time;

    public Music(String text, long start_time) {
        this.text = text;
        this.start_time = start_time;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public long getStart_time() {
        return start_time;
    }

    public void setStart_time(long start_time) {
        this.start_time = start_time;
    }

    @Override
    public String toString() {
        return "Music{" +
                "text='" + text + '\'' +
                ", start_time=" + start_time +
                '}';
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值