欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

surfaceview

程序员文章站 2022-03-29 19:24:50
...

@[toc] surfaceview

播放视频

activity

package com.example.day11_surfaceview_exe;

import android.content.pm.ActivityInfo;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
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.ProgressBar;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {

    private SurfaceView surface;
    private SurfaceHolder holder;
    private MediaPlayer player;
    private Button start;
    private Button pause;
    private SeekBar pro;
    private Button previous;
    private Button next;
    private Button change;
    private Timer timer = new Timer();
    private boolean isLANDSCAP;

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 101) {
                int position = player.getCurrentPosition();
                int duration = player.getDuration();
                int progress = position * 100 / duration;
                pro.setProgress(progress);

                //总时长
                int min = duration / (1000 * 60);
                int sec = duration / 1000 % 60;
                String time_w = "";
                if (min < 10) {
                    time_w += "0";
                }
                time_w += min + ":";
                if (sec < 10) {
                    time_w += "0";
                }
                time_w += sec;
                tvWei.setText(time_w);

                //已播放时长
                int min_t = position / (1000 * 60);
                int sec_t = position / 1000 % 60;
                String time_t = "";
                if (min_t < 10) {
                    time_t += "0";
                }
                time_t += min_t + ":";
                if (sec_t < 10) {
                    time_t += "0";
                }
                time_t += sec_t;
                tvTou.setText(time_t);
            }
        }
    };
    private TextView tvTou;
    private TextView tvWei;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        player = new MediaPlayer();
        initView();
        initPlayer();
    }

    private void initPlayer() {
        try {
            player.setDataSource("http://vd3.bdstatic.com/mda-jk060vvmi12xmdc9/mda-jk060vvmi12xmdc9.mp4");
            player.prepareAsync();
            player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    player.start();
                    //进度
                    initTimer();
                }
            });


        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void initTimer() {
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                handler.sendEmptyMessage(101);
            }
        }, 0, 500);
    }

    private void initView() {
        surface = (SurfaceView) findViewById(R.id.surface);
        start = (Button) findViewById(R.id.start);
        pro = (SeekBar) findViewById(R.id.pro);
        previous = (Button) findViewById(R.id.previous);
        next = (Button) findViewById(R.id.next);
        change = (Button) findViewById(R.id.change);
        tvTou = (TextView) findViewById(R.id.tv_tou);
        tvWei = (TextView) findViewById(R.id.tv_wei);

        holder = surface.getHolder();
        //添加接口,以便回调接口
        holder.addCallback(this);

        start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (player.isPlaying()) {
                    player.pause();
                    start.setBackgroundResource(R.drawable.playbar_btn_play);
                } else {
                    player.start();
                    start.setBackgroundResource(R.drawable.playbar_btn_pause);
                }
            }
        });

        change.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isLANDSCAP) {
                    //切换成竖屏
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                    isLANDSCAP = false;
                } else {
                    //切换成横屏
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                    isLANDSCAP = true;
                }
            }
        });

        player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                Toast.makeText(MainActivity.this, "播放完毕!", Toast.LENGTH_SHORT).show();
            }
        });

        pro.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (fromUser) {
                    player.seekTo(progress * player.getDuration() / 100);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        //显示在surfaceview上
        player.setDisplay(holder);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        if (player != null) {
            //释放资源
            player.release();
            player = null;
        }
    }
}


歌词滚动

activity

package com.example.day_surface_view_sing_word;

import android.Manifest;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;

import com.example.day_surface_view_sing_word.bean.Sing;
import com.google.gson.Gson;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {

    private static final String TAG = "MainActivity";
    private String Alyric = "{\"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 String lyric;
    private List<Sing> list = new ArrayList<>();
    private SurfaceView sfv;
    private SeekBar seek;
    private SurfaceHolder holder;
    private Path path = new Path();
    private int position;
    private Timer timer = new Timer();
    private MediaPlayer player;
    private Handler handler = new Handler();
    private Button start;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(new String[]{
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE
            }, 100);
        }
        initView();

        initLyric();

        initPlayer();

        initTimer();
    }

    private void initTimer() {
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                //获取当前播放的进度
                int currentPosition = player.getCurrentPosition();

                int duration = player.getDuration();

                final int progress = currentPosition * 100 / duration;

                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        seek.setProgress(progress);
                    }
                });

                //歌词跟随
                for (int i = 0; i < list.size(); i++) {
                    if (list.get(i).getSingTime() > currentPosition) {
                        position = i - 1;
                        break;
                    }
                }
            }
        }, 0, 100);
    }

    private void initPlayer() {
        //创建对象
        player = new MediaPlayer();
        //判断是否存在
        if (player != null) {
            //重置
            player.reset();
            try {
                //设置播放的资源
                player.setDataSource("/storage/emulated/0/Music/凤凰传奇 - 最炫民族风(Live).mp3");
                //异步准备
                player.prepareAsync();
                //监听
                player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        //启动
                        player.start();
                        start.setBackgroundResource(R.drawable.playbar_btn_pause);
                    }
                });
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void initLyric() {
        //获取歌词
        lyric = new Gson().fromJson(Alyric, Lyric.class).getLrc().getLyric();

        //切割歌词
        String[] split = lyric.split("\n");
        for (int i = 0; i < split.length; i++) {

            String[] song = split[i].split("\\[|\\:|\\.|\\]");
            if (song.length > 4) {
                String min = song[1];
                Log.d(TAG, "initLyric: 分" + min);
                String sec = song[2];
                Log.d(TAG, "initLyric: 秒" + sec);
                String msec = song[3];
                Log.d(TAG, "initLyric:毫秒" + msec);
                String texts = song[4];
                Log.d(TAG, "initLyric:歌词" + texts);

                int times = Integer.parseInt(min) * 60 * 1000 + Integer.parseInt(sec) * 1000 + Integer.parseInt(msec);

                Sing sing = new Sing(texts, times);

                list.add(sing);

            }

        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        new SongThread().start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        if (player != null) {
            player.release();
            player = null;
        }

        if (timer != null) {
            timer.cancel();
        }
    }

    private void initView() {
        sfv = (SurfaceView) findViewById(R.id.sfv);
        seek = (SeekBar) findViewById(R.id.seek);

        holder = sfv.getHolder();
        holder.addCallback(this);


        seek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                int duration = player.getDuration();
                if (fromUser) {
                    player.seekTo(progress * duration / 100);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

        start = (Button) findViewById(R.id.start);

        start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (player.isPlaying()) {
                    player.pause();
                    start.setBackgroundResource(R.drawable.playbar_btn_play);
                } else {
                    player.start();
                    start.setBackgroundResource(R.drawable.playbar_btn_pause);
                }
            }
        });
    }

    class SongThread extends Thread {
        @Override
        public void run() {
            super.run();
            //正在播放
            Paint paint = new Paint();
            paint.setColor(Color.RED);
            paint.setTextSize(60);
            paint.setStyle(Paint.Style.FILL);
            paint.setAntiAlias(true);
            //已播或者未播
            Paint paint2 = new Paint();
            paint2.setColor(Color.GREEN);
            paint2.setTextSize(60);
            paint2.setStyle(Paint.Style.FILL);
            paint2.setAntiAlias(true);

            while (true) {
                Canvas canvas = holder.lockCanvas();
                if (canvas == null) {
                    break;
                }
                path = new Path();
                canvas.drawColor(Color.WHITE);
                //播过的
                for (int i = 0; i <= position - 1; i++) {
                    canvas.drawText(list.get(i).getText(), 100, 700 - (position - i) * 100, paint2);
                    canvas.drawPath(path, paint2);
                }

                //正在播的
                canvas.drawText(list.get(position).getText(), 100, 700, paint);
                canvas.drawPath(path, paint);

                //未播的
                for (int i = position + 1; i < list.size() - 1; i++) {
                    canvas.drawText(list.get(i).getText(), 100, 700 + (i - position) * 100, paint2);
                    canvas.drawPath(path, paint2);
                }


                holder.unlockCanvasAndPost(canvas);
            }
        }
    }
}

画板

activity

package com.example.day1113_surfaceview;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {

    private Button butC;
    private SurfaceView sfv;
    private Paint paint;
    private Path path = new Path();
    private SurfaceHolder holder;
    private Button red;
    private Button green;
    private Button blue;
    private Button yellow;
    private Button black;
    private Button purple;
    private Button gray;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        butC = (Button) findViewById(R.id.but_c);
        sfv = (SurfaceView) findViewById(R.id.sfv);
        red = (Button) findViewById(R.id.red);
        green = (Button) findViewById(R.id.green);
        blue = (Button) findViewById(R.id.blue);
        yellow = (Button) findViewById(R.id.yellow);
        black = (Button) findViewById(R.id.black);
        purple = (Button) findViewById(R.id.purple);
        gray = (Button) findViewById(R.id.gray);
        holder = sfv.getHolder();
        holder.addCallback(this);

        red.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                paint.setColor(Color.RED);
            }
        });
        green.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                paint.setColor(Color.GREEN);
            }
        });
        blue.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                paint.setColor(Color.BLUE);
            }
        });
        yellow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                paint.setColor(Color.YELLOW);
            }
        });
        black.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                paint.setColor(Color.BLACK);
            }
        });
        purple.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                paint.setColor(0xFFFF00FF);
            }
        });
        gray.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                paint.setColor(Color.GRAY);
            }
        });


        butC.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                path.reset();
            }
        });

        sfv.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                int action = event.getAction();
                float x = event.getX();
                float y = event.getY();
                if (action == MotionEvent.ACTION_DOWN) {
                    path.moveTo(x, y);
                } else if (action == MotionEvent.ACTION_MOVE) {
                    path.lineTo(x, y);
                }
                return true;
            }
        });


    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        new HuaBanThread().start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

    }


    class HuaBanThread extends Thread {
        @Override
        public void run() {
            super.run();
            paint = new Paint();
            paint.setColor(Color.RED);
            paint.setStrokeWidth(2);
            paint.setStyle(Paint.Style.STROKE);//空心

            while (true) {
                Canvas canvas = holder.lockCanvas();
                if (canvas == null) {
                    break;
                }
                canvas.drawColor(Color.WHITE);
                canvas.drawPath(path, paint);
                holder.unlockCanvasAndPost(canvas);
            }

        }
    }
}

上一篇: SurfaceView

下一篇: SurfaceView