Android 仿抖音播放视频+录制播放+列表

一、项目中的配置

1.在项目的build的文件中添加

在repositories里添加

maven { url 'https://jitpack.io' }

在allprojects里添加

maven { url 'https://jitpack.io' }
flatDir {
            dirs 'libs'
        }

2.在当前module中的build文件中添加依赖

    implementation 'com.jakewharton:butterknife:8.8.1'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
    // 导入腾讯云直播 SDK aar
    implementation(name: 'LiteAVSDK_UGC_5.0.4978', ext: 'aar')
    implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.35'
    //glide
    implementation 'com.github.bumptech.glide:glide:4.6.1'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.6.1'
    //播放器
    implementation 'cn.jzvd:jiaozivideoplayer:6.2.12'
    //视频缓存
    implementation 'com.danikula:videocache:2.7.1'
    //权限
    implementation 'pub.devrel:easypermissions:1.3.0'
    implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0-alpha-5'
    implementation 'com.android.support:recyclerview-v7:28.0.0'

需要将minSdkVersion 改成16

3.在清单文件中添加权限

<uses-permission android:name="android.permission.INTERNET"/>

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

    <uses-permission android:name="android.permission.CALL_PHONE"/>

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <uses-permission android:name="android.permission.READ_LOGS" />

    <uses-permission android:name="android.permission.RECORD_AUDIO"/>

    <uses-permission android:name="android.permission.CAMERA"/>

    <uses-feature android:name="android.hardware.Camera"/>

    <uses-feature android:name="android.hardware.camera.autofocus"/>

    <uses-feature android:name="android.hardware.camera2"/>

在mipmap-xhdpi有两张图片,是控制暂停和播放的图片

二、逻辑代码

1.MainActivity

public class MainActivity extends AppCompatActivity {
    @BindView(R.id.btn_list)
    Button btnList;
    @BindView(R.id.btn_record)
    Button btnList2;
    @BindView(R.id.btn_page2)
    Button btnPage2;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
    }
    @OnClick({ R.id.btn_list, R.id.btn_record,  R.id.btn_page2})
    public void onViewClicked(View view) {
        Intent intent = new Intent();
        switch (view.getId()) {
            case R.id.btn_list://列表页面
                intent.setClass(MainActivity.this, ListActivity.class);
                break;
            case R.id.btn_record://录制页面
                intent.setClass(MainActivity.this, RecordActivity.class);
                break;
            case R.id.btn_page2://翻页页面
                intent.setClass(MainActivity.this, Page2Activity.class);
                break;
        }
        startActivity(intent);
    }
}

对应的xml文件

<android.support.constraint.ConstraintLayout 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">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <Button
            android:id="@+id/btn_page2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="翻页2" />
        <Button
            android:id="@+id/btn_list"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="列表" />
        <Button
            android:id="@+id/btn_record"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="录制" />
    </LinearLayout>
</android.support.constraint.ConstraintLayout>

2.ListActivity列表页面

public class ListActivity extends AppCompatActivity {

    @BindView(R.id.rv_list)
    RecyclerView rvList;
    private ArrayList<String> urlList;
    private ListVideoAdapter videoAdapter;
    private int firstVisibleItem;
    private int lastVisibleItem;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list);
        ButterKnife.bind(this);

        urlList = new ArrayList<>();
        urlList.add("http://chuangfen.oss-cn-hangzhou.aliyuncs.com/public/attachment/201805/100651/201805181532123423.mp4");
        urlList.add("http://chuangfen.oss-cn-hangzhou.aliyuncs.com/public/attachment/201803/100651/201803151735198462.mp4");
        urlList.add("http://chuangfen.oss-cn-hangzhou.aliyuncs.com/public/attachment/201803/100651/201803150923220770.mp4");
        urlList.add("http://chuangfen.oss-cn-hangzhou.aliyuncs.com/public/attachment/201803/100651/201803150922255785.mp4");
        urlList.add("http://chuangfen.oss-cn-hangzhou.aliyuncs.com/public/attachment/201803/100651/201803150920130302.mp4");
        urlList.add("http://chuangfen.oss-cn-hangzhou.aliyuncs.com/public/attachment/201803/100651/201803141625005241.mp4");
        urlList.add("http://chuangfen.oss-cn-hangzhou.aliyuncs.com/public/attachment/201803/100651/201803141624378522.mp4");
        urlList.add("http://chuangfen.oss-cn-hangzhou.aliyuncs.com/public/attachment/201803/100651/201803131546119319.mp4");

        videoAdapter = new ListVideoAdapter(urlList);
        rvList.setLayoutManager(new LinearLayoutManager(ListActivity.this));
        rvList.setAdapter(videoAdapter);

        addListener();

    }

    private void addListener() {


        rvList.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
                firstVisibleItem = layoutManager.findFirstVisibleItemPosition();
                lastVisibleItem = layoutManager.findLastVisibleItemPosition();

            }

            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                switch (newState) {
                    case RecyclerView.SCROLL_STATE_IDLE://停止滚动
                        /**在这里执行,视频的自动播放与停止*/
                        autoPlayVideo(recyclerView);
                        break;
                    case RecyclerView.SCROLL_STATE_DRAGGING://拖动
                        autoPlayVideo(recyclerView);
                        break;
                    case RecyclerView.SCROLL_STATE_SETTLING://惯性滑动
                        JZVideoPlayer.releaseAllVideos();
                        break;
                }

            }
        });
    }

    /**
     * 自动播放
     */
    private void autoPlayVideo(RecyclerView recyclerView) {

        if (firstVisibleItem == 0 && lastVisibleItem == 0 && recyclerView.getChildAt(0) != null) {

            MyVideoPlayer videoView = null;
            if (recyclerView != null && recyclerView.getChildAt(0) != null) {
                videoView = recyclerView.getChildAt(0).findViewById(R.id.mp_video);
            }
            if (videoView != null) {
                if (videoView.currentState == JZVideoPlayer.CURRENT_STATE_NORMAL || videoView.currentState == JZVideoPlayer.CURRENT_STATE_PAUSE) {
                    videoView.startVideo();
                }
            }
        }

        for (int i = 0; i <= lastVisibleItem; i++) {
            if (recyclerView == null || recyclerView.getChildAt(i) == null) {
                return;
            }


            MyVideoPlayer
                    videoView = recyclerView.getChildAt(i).findViewById(R.id.mp_video);
            if (videoView != null) {

                Rect rect = new Rect();
                //获取视图本身的可见坐标,把值传入到rect对象中
                videoView.getLocalVisibleRect(rect);
                //获取视频的高度
                int videoHeight = videoView.getHeight();

                if (rect.top <= 100 && rect.bottom >= videoHeight) {
                    if (videoView.currentState == JZVideoPlayer.CURRENT_STATE_NORMAL || videoView.currentState == JZVideoPlayer.CURRENT_STATE_PAUSE) {
                        videoView.startVideo();
                    }
                    return;
                }

                JZVideoPlayer.releaseAllVideos();

            } else {
                JZVideoPlayer.releaseAllVideos();
            }

        }

    }


    @Override
    public void onPause() {
        super.onPause();
        JZVideoPlayer.releaseAllVideos();
    }


    class ListVideoAdapter extends BaseRecAdapter<String, VideoViewHolder> {


        public ListVideoAdapter(List<String> list) {
            super(list);
        }

        @Override
        public void onHolder(VideoViewHolder holder, String bean, int position) {
            holder.mp_video.setUp(bean, JZVideoPlayerStandard.CURRENT_STATE_NORMAL);
            if (position == 0) {
                holder.mp_video.startVideo();
            }
            Glide.with(context).load(bean).into(holder.mp_video.thumbImageView);
            holder.tv_title.setText("第" + position + "个视频");
        }

        @Override
        public VideoViewHolder onCreateHolder() {
            return new VideoViewHolder(getViewByRes(R.layout.item_video));

        }


    }

    public class VideoViewHolder extends BaseRecViewHolder {
        public View rootView;
        public MyVideoPlayer mp_video;
        public TextView tv_title;

        public VideoViewHolder(View rootView) {
            super(rootView);
            this.rootView = rootView;
            this.mp_video = rootView.findViewById(R.id.mp_video);
            this.tv_title = rootView.findViewById(R.id.tv_title);
        }

    }
}

对应的xml布局

<android.support.constraint.ConstraintLayout 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=".activity.ListActivity">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</android.support.constraint.ConstraintLayout>

3.RecordActivity录制页面

/**
 * 录制
 */
public class RecordActivity extends AppCompatActivity implements SurfaceHolder.Callback, EasyPermissions.PermissionCallbacks {

    @BindView(R.id.sv_record)
    SurfaceView svRecord;
    @BindView(R.id.btn_start)
    Button btnStart;
    @BindView(R.id.btn_end)
    Button btnEnd;
    @BindView(R.id.btn_switch)
    Button btnSwitch;
    @BindView(R.id.pb_record)
    SeekBar pbRecord;
    private SurfaceHolder surfaceHolder;
    private Camera camera;
    private MediaRecorder mediaRecorder;
    //当前打开的摄像头标记 1--后,2--前
    private int currentCameraType = -1;
    private boolean isRecording;
    private File temFile;
    private MyTimer myTimer;
    private static final long TIME_MAX = 15 * 1000;
    private static final long TIME_INTERVAL = 500;

    private static final int RC_STORAGE = 1001;

    private Camera.Size size;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_record);
        ButterKnife.bind(this);

        initView();
    }

    private void initView() {
        surfaceHolder = svRecord.getHolder();
        surfaceHolder.addCallback(this);
        //设置一些参数方便后面绘图
        svRecord.setFocusable(true);
        svRecord.setKeepScreenOn(true);
        svRecord.setFocusableInTouchMode(true);

        pbRecord.setMax(100);
        pbRecord.setProgress(0);
    }

    @OnClick({R.id.btn_start, R.id.btn_end, R.id.btn_switch})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            //开始录制
            case R.id.btn_start:
                startRecord();
                break;
            //停止录制
            case R.id.btn_end:
                stopRecord(false);
                break;
            //切换摄像头
            case R.id.btn_switch:
                stopPreview();
                if (currentCameraType == 1) {
                    camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
                    currentCameraType = 2;
                    btnSwitch.setText("前");
                } else {
                    camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
                    currentCameraType = 1;
                    btnSwitch.setText("后");
                }

                startPreview();
                break;
        }
    }

    /**
     * 开始录制
     */
    private void startRecord() {
        if (mediaRecorder == null) {
            mediaRecorder = new MediaRecorder();
        }
        temFile = getTemFile();


        try {
            camera.unlock();
            mediaRecorder.setCamera(camera);
            //从相机采集视频
            mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
            // 从麦克采集音频信息
            mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            //编码格式
            mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
            mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

            mediaRecorder.setVideoSize(size.width, size.height);

            //每秒的帧数
            mediaRecorder.setVideoFrameRate(24);
            // 设置帧频率,然后就清晰了
            mediaRecorder.setVideoEncodingBitRate(1 * 1024 * 1024 * 100);


            mediaRecorder.setOutputFile(temFile.getAbsolutePath());
            mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
            //解决录制视频, 播放器横向问题
            if (currentCameraType == 1) {
                //后置
                mediaRecorder.setOrientationHint(90);
            } else {
                //前置
                mediaRecorder.setOrientationHint(270);
            }
            mediaRecorder.prepare();
            //正式录制
            mediaRecorder.start();

            myTimer = new MyTimer(TIME_MAX, TIME_INTERVAL);
            myTimer.start();

            isRecording = true;
            showtoast("开始录制");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        startPreview();
    }

    /**
     * 获取临时文件目录
     *
     * @return
     */
    private File getTemFile() {
        String basePath = Environment.getExternalStorageDirectory().getPath() + "/doudemo/";

        File baseFile = new File(basePath);
        if (!baseFile.exists()) {
            baseFile.mkdirs();
        }

        File temp = new File(basePath + System.currentTimeMillis() + ".mp4");

        return temp;
    }

    /**
     * 停止录制
     */
    private void stopRecord(boolean delete) {
        if (mediaRecorder == null) {
            return;
        }
        if (myTimer != null) {
            myTimer.cancel();
        }

        try {
            mediaRecorder.stop();
        } catch (Exception e) {
            e.printStackTrace();
        }
        mediaRecorder.reset();
        mediaRecorder.release();
        mediaRecorder = null;
        if (camera != null) {
            camera.lock();
        }
        isRecording = false;

        if (delete) {
            if (temFile != null && temFile.exists()) {
                temFile.delete();
            }
        } else {
            //停止预览
            stopPreview();

            Intent intent = new Intent(RecordActivity.this, PrepareActivity.class);
            intent.putExtra(PrepareActivity.VIDEO_PATH, temFile.getPath());
            startActivity(intent);

        }
        showtoast("停止录制");
    }


    /**
     * 开始预览
     */
    private void startPreview() {
        if (svRecord == null || surfaceHolder == null) {
            return;
        }


        if (camera == null) {
            camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
            currentCameraType = 1;
            btnSwitch.setText("后");
        }


        try {
            camera.setPreviewDisplay(surfaceHolder);
            Camera.Parameters parameters = camera.getParameters();

            camera.setDisplayOrientation(90);

            //实现Camera自动对焦
            List<String> focusModes = parameters.getSupportedFocusModes();
            if (focusModes != null) {
                for (String mode : focusModes) {
                    mode.contains("continuous-video");
                    parameters.setFocusMode("continuous-video");
                }
            }

            List<Camera.Size> sizes = parameters.getSupportedVideoSizes();
            if (sizes.size() > 0) {
                size = sizes.get(sizes.size() - 1);
            }

            camera.setParameters(parameters);
            camera.startPreview();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 停止预览
     */
    private void stopPreview() {
        //停止预览并释放摄像头资源
        if (camera == null) {
            return;
        }

        camera.setPreviewCallback(null);
        camera.stopPreview();
        camera.release();
        camera = null;
    }


    @Override
    protected void onStop() {
        super.onStop();
        stopPreview();
        stopRecord(true);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        surfaceHolder = holder;
        requestPermision();
    }


    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        surfaceHolder = holder;
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        //停止预览并释放摄像头资源
        stopPreview();
        //停止录制
        startRecord();
    }

    private void requestPermision() {
        String[] perms = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO};
        if (EasyPermissions.hasPermissions(this, perms)) {
            // Already have permission, do the thing
            startPreview();
            // ...
        } else {
            // Do not have permissions, request them now
            EasyPermissions.requestPermissions(this, "我们的app需要以下权限",
                    RC_STORAGE, perms);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        // Forward results to EasyPermissions
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }

    @Override
    public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
        // Some permissions have been granted
        startPreview();
    }

    @Override
    public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
        // Some permissions have been denied
        finish();
    }


    public class MyTimer extends CountDownTimer {
        /**
         * @param millisInFuture    The number of millis in the future from the call
         *                          to {@link #start()} until the countdown is done and {@link #onFinish()}
         *                          is called.
         * @param countDownInterval The interval along the way to receive
         *                          {@link #onTick(long)} callbacks.
         */
        public MyTimer(long millisInFuture, long countDownInterval) {
            super(millisInFuture, countDownInterval);
        }

        @Override
        public void onTick(long millisUntilFinished) {
            int progress = (int) ((TIME_MAX - millisUntilFinished) / (double) TIME_MAX * 100);
            Log.e("cheng", "millisUntilFinished=" + progress);
            pbRecord.setProgress(progress);

        }

        @Override
        public void onFinish() {
            stopRecord(false);
        }
    }

    /**
     * @param s
     */
    public void showtoast(@NonNull String s) {
        Toast.makeText(RecordActivity.this, s, Toast.LENGTH_SHORT).show();
    }

}

对应的xml布局

<android.support.constraint.ConstraintLayout 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=".activity.RecordActivity">

    <SurfaceView
        android:id="@+id/sv_record"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <Button
        android:id="@+id/btn_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="start"
        app:layout_constraintBottom_toBottomOf="parent" />

    <Button
        android:id="@+id/btn_switch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="switch"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_end"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="end"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent" />

    <SeekBar
        android:id="@+id/pb_record"
        android:layout_width="match_parent"
        android:layout_height="10dp"
        android:max="100"
        android:progress="0" />
</android.support.constraint.ConstraintLayout>

4.录制完后会直接进行播放,单击会进入全屏,播放完一遍后会出现暂停和播放按钮

PrepareActivity视频预览

/**

  • 视频预览
    */
    public class PrepareActivity extends AppCompatActivity {

    @BindView(R.id.mp_video)
    MyVideoPlayer mpVideo;

    public static final String VIDEO_PATH = “VIDEO_PATH”;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_prepare);
    ButterKnife.bind(this);
    initView();
    }

    private void initView() {
    String path = getIntent().getStringExtra(VIDEO_PATH);
    if (!TextUtils.isEmpty(path)) {
    mpVideo.setUp(path, JZVideoPlayerStandard.CURRENT_STATE_NORMAL);
    mpVideo.startVideo();
    }
    }
    }

对应的xml布局

<android.support.constraint.ConstraintLayout 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=".activity.PrepareActivity">

    <movie.bw.com.douyinbofang.widget.MyVideoPlayer
        android:id="@+id/mp_video"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</android.support.constraint.ConstraintLayout>

5.Page2Activity翻页页面

/**
 * 翻页2
 */
public class Page2Activity extends AppCompatActivity {

    @BindView(R.id.rv_page2)
    RecyclerView rvPage2;
    private List<String> urlList;
    private ListVideoAdapter videoAdapter;
    private PagerSnapHelper snapHelper;
    private LinearLayoutManager layoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_page2);
        ButterKnife.bind(this);
        initView();
        addListener();
    }


    private void initView() {
        urlList = new ArrayList<>();
        urlList.add("http://chuangfen.oss-cn-hangzhou.aliyuncs.com/public/attachment/201811/26/09/5bfb4c55633c9.mp4");
        urlList.add("http://chuangfen.oss-cn-hangzhou.aliyuncs.com/public/attachment/201805/100651/201805181532123423.mp4");
        urlList.add("http://chuangfen.oss-cn-hangzhou.aliyuncs.com/public/attachment/201803/100651/201803151735198462.mp4");
        urlList.add("http://chuangfen.oss-cn-hangzhou.aliyuncs.com/public/attachment/201803/100651/201803150923220770.mp4");
        urlList.add("http://chuangfen.oss-cn-hangzhou.aliyuncs.com/public/attachment/201803/100651/201803150922255785.mp4");
        urlList.add("http://chuangfen.oss-cn-hangzhou.aliyuncs.com/public/attachment/201803/100651/201803150920130302.mp4");
        urlList.add("http://chuangfen.oss-cn-hangzhou.aliyuncs.com/public/attachment/201803/100651/201803141625005241.mp4");
        urlList.add("http://chuangfen.oss-cn-hangzhou.aliyuncs.com/public/attachment/201803/100651/201803141624378522.mp4");
        urlList.add("http://chuangfen.oss-cn-hangzhou.aliyuncs.com/public/attachment/201803/100651/201803131546119319.mp4");


        snapHelper = new PagerSnapHelper();
        snapHelper.attachToRecyclerView(rvPage2);


        videoAdapter = new ListVideoAdapter(urlList);
        layoutManager = new LinearLayoutManager(Page2Activity.this, LinearLayoutManager.VERTICAL, false);
        rvPage2.setLayoutManager(layoutManager);
        rvPage2.setAdapter(videoAdapter);

    }

    private void addListener() {

        rvPage2.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {


            }

            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                switch (newState) {
                    case RecyclerView.SCROLL_STATE_IDLE://停止滚动
                        View view = snapHelper.findSnapView(layoutManager);
                        JZVideoPlayer.releaseAllVideos();
                        RecyclerView.ViewHolder viewHolder = recyclerView.getChildViewHolder(view);
                        if (viewHolder != null && viewHolder instanceof VideoViewHolder) {
                            ((VideoViewHolder) viewHolder).mp_video.startVideo();
                        }

                        break;
                    case RecyclerView.SCROLL_STATE_DRAGGING://拖动
                        break;
                    case RecyclerView.SCROLL_STATE_SETTLING://惯性滑动
                        break;
                }

            }
        });
    }


    @Override
    public void onPause() {
        super.onPause();
        JZVideoPlayer.releaseAllVideos();
    }


    class ListVideoAdapter extends BaseRecAdapter<String, VideoViewHolder> {


        public ListVideoAdapter(List<String> list) {
            super(list);
        }

        @Override
        public void onHolder(VideoViewHolder holder, String bean, int position) {
            ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
            layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;

            holder.mp_video.setUp(bean, JZVideoPlayerStandard.CURRENT_STATE_NORMAL);
            if (position == 0) {
                holder.mp_video.startVideo();
            }
            Glide.with(context).load(bean).into(holder.mp_video.thumbImageView);
            holder.tv_title.setText("第" + position + "个视频");
        }

        @Override
        public VideoViewHolder onCreateHolder() {
            return new VideoViewHolder(getViewByRes(R.layout.item_page2));

        }


    }

    public class VideoViewHolder extends BaseRecViewHolder {
        public View rootView;
        public MyVideoPlayer mp_video;
        public TextView tv_title;

        public VideoViewHolder(View rootView) {
            super(rootView);
            this.rootView = rootView;
            this.mp_video = rootView.findViewById(R.id.mp_video);
            this.tv_title = rootView.findViewById(R.id.tv_title);
        }

    }
}

对应的xml布局

<android.support.constraint.ConstraintLayout 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=".activity.Page2Activity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_page2"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</android.support.constraint.ConstraintLayout>

三、工具类

1.BaseRecAdapter

public abstract class BaseRecAdapter<T, K extends BaseRecViewHolder> extends RecyclerView.Adapter<K> {

    private List<T> list;
    private onItemClickListener itemClickListener;
    private OnItemLongClickListener itemLongClickListener;
    public Context context;

    public OnItemLongClickListener getItemLongClickListener() {
        return itemLongClickListener;
    }

    public void setItemLongClickListener(OnItemLongClickListener itemLongClickListener) {
        this.itemLongClickListener = itemLongClickListener;
    }

    public onItemClickListener getItemClickListener() {
        return itemClickListener;
    }

    public void setItemClickListener(onItemClickListener itemClickListener) {
        this.itemClickListener = itemClickListener;
    }

    public BaseRecAdapter(List<T> list) {
        this.list = list;
    }

    @Override
    public K onCreateViewHolder(ViewGroup parent, int viewType) {
        context = parent.getContext();
        K holder = onCreateHolder();
        //绑定listener
        bindListener(holder);
        return holder;
    }

    @Override
    public void onBindViewHolder(K holder, int position) {

        onHolder(holder, list.get(position), position);

    }


    @Override
    public int getItemCount() {
        return list == null ? 0 : list.size();
    }


    /**
     * 填充数据
     *
     * @param holder
     * @param position
     */
    public abstract void onHolder(K holder, T bean, int position);


    public abstract K onCreateHolder();


    /**
     * 通过资源res获得view
     *
     * @param res
     * @return
     */
    public View getViewByRes(int res) {
        return LayoutInflater.from(context).inflate(res, null);
    }

    /**
     * 通过资源res获得view
     *
     * @param res
     * @return
     */
    public View getViewByRes(int res, ViewGroup prent) {
        return LayoutInflater.from(context).inflate(res, prent);
    }

    /**
     * 绑定事件
     *
     * @param holder
     */
    private void bindListener(final K holder) {

        if (holder == null) {
            return;
        }
        View itemView = holder.itemView;
        if (itemView == null) {
            return;
        }
        ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        itemView.setLayoutParams(params);
        if (getItemClickListener() != null) {
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    getItemClickListener().onItemClick(BaseRecAdapter.this, v, holder.getLayoutPosition());
                }
            });
        }
        if (getItemLongClickListener() != null) {
            itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    return getItemLongClickListener().onItemLongClick(BaseRecAdapter.this, v, holder.getLayoutPosition());
                }
            });
        }
    }


    public interface onItemClickListener {
        void onItemClick(BaseRecAdapter adapter, View view, int position);
    }

    public interface OnItemLongClickListener {
        boolean onItemLongClick(BaseRecAdapter adapter, View view, int position);
    }


    public void setNewData(List<T> lt) {
        if (list == null) {
            list = new ArrayList<T>();
        }
        if (lt == null) {
            lt = new ArrayList<T>();
        }
        list = lt;
        notifyDataSetChanged();
    }

    public List<T> getData() {
        return list;
    }
}

2.BaseRecViewHolder

public class BaseRecViewHolder extends RecyclerView.ViewHolder {
public BaseRecViewHolder(View itemView) {
super(itemView);
}
}

3.MyApp
需要在清单文件中关联
public class MyApp extends Application {

private HttpProxyCacheServer proxy;

public static HttpProxyCacheServer getProxy(Context context) {
    MyApp app = (MyApp) context.getApplicationContext();
    return app.proxy == null ? (app.proxy = app.newProxy()) : app.proxy;
}

private HttpProxyCacheServer newProxy() {
    return new HttpProxyCacheServer.Builder(this)
            .maxCacheSize(1024 * 1024 * 1024)       // 1 Gb for cache
            .fileNameGenerator(new MyFileNameGenerator())
            .build();
}

@Override
public void onCreate() {
    super.onCreate();
}

}

4.BaseFragment

public abstract class BaseFragment extends Fragment {

    protected String TAG = getClass().getSimpleName();
    protected Context context;
    private View rootView;

    protected abstract int getLayoutId();

    protected abstract void initView();


    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        this.context = context;
    }

    //Fragment的View加载完毕的标记
    private boolean isViewCreated;
    //Fragment对用户可见的标记
    public boolean isUIVisible;
    protected boolean isLoadCompleted;
    Unbinder unbinder;


    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        //isVisibleToUser这个boolean值表示:该Fragment的UI 用户是否可见
        if (isVisibleToUser && !isLoadCompleted) {
            isUIVisible = true;
            lazyLoad();
        } else {
            isUIVisible = false;
        }
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (getUserVisibleHint() && !isLoadCompleted) {
            // 此处不需要判断isViewCreated,因为这个方法在onCreateView方法之后执行
            lazyLoad();
        }
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        rootView = inflater.inflate(getLayoutId(), container, false);
        unbinder = ButterKnife.bind(this, rootView);
        isViewCreated = true;
        initView();
        return rootView;
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        isUIVisible = !hidden;
    }

    protected void lazyLoad() {
        //这里进行双重标记判断,是因为setUserVisibleHint会多次回调,并且会在onCreateView执行前回调,必须确保onCreateView加载完毕且页面可见,才加载数据
        if (isViewCreated && isUIVisible) {
            loadData();
            //数据加载完毕,恢复标记,防止重复加载
//            isViewCreated = false;
//            isUIVisible = false;
            isLoadCompleted = true;
        }
    }


    protected abstract void loadData();

    public boolean onBackPressed() {
        assert getFragmentManager() != null;
        if (getFragmentManager().getBackStackEntryCount() > 0) {
            getFragmentManager().popBackStack();
            return true;
        }
        return false;
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        if (unbinder != null) {
            unbinder.unbind();
        }
    }
}

5.VideoFragment

public class VideoFragment extends BaseFragment {
    @BindView(R.id.txv_video)
    TXCloudVideoView txvVideo;
    @BindView(R.id.rl_back_right)
    RelativeLayout rlBackRight;
    @BindView(R.id.dl_back_play)
    DrawerLayout dlBackPlay;
    @BindView(R.id.iv_play_thun)
    ImageView ivPlayThun;
    private TXVodPlayer mVodPlayer;
    private String url;
    public static final String URL = "URL";

    @Override
    protected int getLayoutId() {
        return R.layout.fm_video;
    }

    @Override
    protected void initView() {

        url = getArguments().getString(URL);
        //创建player对象
        mVodPlayer = new TXVodPlayer(context);
//关键player对象与界面view
        mVodPlayer.setPlayerView(txvVideo);
//        url = "http://v.cctv.com/flash/mp4video6/TMS/2011/01/05/cf752b1c12ce452b3040cab2f90bc265_h264818000nero_aac32-1.mp4";
        mVodPlayer.setLoop(true);

        Glide.with(context)
                .load(url)
                .into(ivPlayThun);
//        dlBackPlay.addDrawerListener(new DrawerLayout.DrawerListener() {
//            @Override
//            public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {
//
//            }
//
//            @Override
//            public void onDrawerOpened(@NonNull View drawerView) {
//                if (mVodPlayer != null) {
//                    mVodPlayer.pause();
//                }
//            }
//
//            @Override
//            public void onDrawerClosed(@NonNull View drawerView) {
//                if (mVodPlayer != null) {
//                    mVodPlayer.resume();
//                }
//            }
//
//            @Override
//            public void onDrawerStateChanged(int newState) {
//
//            }
//        });
//
//
//        //设置菜单内容之外其他区域的背景色
//        dlBackPlay.setScrimColor(Color.TRANSPARENT);
//        //设置 全屏滑动
//        setDrawerRightEdgeSize(getActivity(), dlBackPlay, 1);

    }

    @Override
    protected void loadData() {
        mVodPlayer.startPlay(url);
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);

        if (mVodPlayer == null) {
            return;
        }
        if (isVisibleToUser) {
            mVodPlayer.resume();
        } else {
            mVodPlayer.pause();
        }

    }

    @Override
    public void onResume() {

        super.onResume();
        if (mVodPlayer != null) {
            mVodPlayer.resume();
        }

    }

    @Override
    public void onPause() {
        super.onPause();
        if (mVodPlayer != null) {
            mVodPlayer.pause();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mVodPlayer != null) {
            // true代表清除最后一帧画面
            mVodPlayer.stopPlay(true);
        }
        if (txvVideo != null) {
            txvVideo.onDestroy();
        }
    }


    /**
     * 设置 全屏滑动
     *
     * @param activity
     * @param drawerLayout
     * @param displayWidthPercentage
     */
    private void setDrawerRightEdgeSize(Activity activity, DrawerLayout drawerLayout, float displayWidthPercentage) {
        if (activity == null || drawerLayout == null) return;
        try {
            // 找到 ViewDragHelper 并设置 Accessible 为true
            Field mRightDragger =
                    drawerLayout.getClass().getDeclaredField("mRightDragger");//Right
            mRightDragger.setAccessible(true);
            ViewDragHelper leftDragger = (ViewDragHelper) mRightDragger.get(drawerLayout);

            // 找到 edgeSizeField 并设置 Accessible 为true
            Field edgeSizeField = leftDragger.getClass().getDeclaredField("mEdgeSize");
            edgeSizeField.setAccessible(true);
            int edgeSize = edgeSizeField.getInt(leftDragger);

            // 设置新的边缘大小
            Point displaySize = new Point();
            activity.getWindowManager().getDefaultDisplay().getSize(displaySize);
            edgeSizeField.setInt(leftDragger, Math.max(edgeSize, (int) (displaySize.x *
                    displayWidthPercentage)));
        } catch (NoSuchFieldException e) {
        } catch (IllegalArgumentException e) {
        } catch (IllegalAccessException e) {
        }
    }
}

6.MyFileNameGenerator

public class MyFileNameGenerator implements FileNameGenerator {
    private static final int MAX_EXTENSION_LENGTH = 4;

    @Override
    public String generate(String url) {
        String extension = getExtension(url);
        int dotIndex = url.lastIndexOf('.');

        if (url.length() > 18 && dotIndex > 18) {
            return url.substring(dotIndex - 18);
        }
        String name = ProxyCacheUtils.computeMD5(url);
        return TextUtils.isEmpty(extension) ? name : name + "." + extension;
    }

    private String getExtension(String url) {
        int dotIndex = url.lastIndexOf('.');
        int slashIndex = url.lastIndexOf('/');
        return dotIndex != -1 && dotIndex > slashIndex && dotIndex + 2 + MAX_EXTENSION_LENGTH > url.length() ?
                url.substring(dotIndex + 1, url.length()) : "";
    }
}

7.MyVideoPlayer

public class MyVideoPlayer extends JZVideoPlayerStandard {
    private RelativeLayout rl_touch_help;
    private ImageView iv_start;
    private LinearLayout ll_start;

    private Context context;


    public MyVideoPlayer(Context context) {
        super(context);
        this.context = context;
    }

    public MyVideoPlayer(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }

    @Override
    public void onAutoCompletion() {

        thumbImageView.setVisibility(View.GONE);

        if (currentScreen == SCREEN_WINDOW_FULLSCREEN) {
            onStateAutoComplete();
            setUp((String) getCurrentUrl(), JZVideoPlayer.SCREEN_WINDOW_FULLSCREEN);
        } else {
            super.onAutoCompletion();
            setUp((String) getCurrentUrl(), JZVideoPlayer.CURRENT_STATE_NORMAL);
        }
        //循环播放

        startVideo();
    }

    @Override
    public void setUp(String url, int screen, Object... objects) {

        if (url.startsWith("http")) {
            HttpProxyCacheServer proxy = MyApp.getProxy(context);
            String proxyUrl = proxy.getProxyUrl(url);
            super.setUp(proxyUrl, screen, objects);
        } else {
            super.setUp(url, screen, objects);
        }
    }

    @Override
    public void init(final Context context) {
        super.init(context);

        rl_touch_help = findViewById(R.id.rl_touch_help);
        ll_start = findViewById(R.id.ll_start);
        iv_start = findViewById(R.id.iv_start);
        resetPlayView();

        rl_touch_help.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                resetPlayView();
                if (isPlay()) {
                    fullscreenButton.performClick();
                }

            }
        });

        ll_start.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isPlay()) {
                    goOnPlayOnPause();
                } else {
                    //暂停
                    if (currentState == JZVideoPlayer.CURRENT_STATE_PAUSE) {
                        goOnPlayOnResume();
                    } else {
                        startVideo();
                    }
                }
                resetPlayView();
            }
        });
    }

    @Override
    public void startVideo() {
        if (currentScreen == SCREEN_WINDOW_FULLSCREEN) {
            initTextureView();
            addTextureView();
            AudioManager mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
            mAudioManager.requestAudioFocus(onAudioFocusChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
            JZUtils.scanForActivity(getContext()).getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

            JZMediaManager.setDataSource(dataSourceObjects);
            JZMediaManager.setCurrentDataSource(JZUtils.getCurrentFromDataSource(dataSourceObjects, currentUrlMapIndex));
            JZMediaManager.instance().positionInList = positionInList;
            onStatePreparing();
            ll_start.setVisibility(VISIBLE);
        } else {
            super.startVideo();
            ll_start.setVisibility(GONE);
        }
        resetPlayView();
    }

    @Override
    public void startWindowTiny() {
    }

    private void resetPlayView() {
        if (isPlay()) {
            iv_start.setBackgroundResource(R.mipmap.video_play_parse);
        } else {
            iv_start.setBackgroundResource(R.mipmap.stop);
        }
    }

    /**
     * 是否播放
     *
     * @return
     */
    private boolean isPlay() {
        if (currentState == CURRENT_STATE_PREPARING || currentState == CURRENT_STATE_PLAYING || currentState == -1) {
            return true;
        }

        return false;
    }

}

四、其中的xml布局

1.fm_video.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/dl_back_play"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageView
            android:id="@+id/iv_play_thun"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />


        <com.tencent.rtmp.ui.TXCloudVideoView
            android:id="@+id/txv_video"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <RelativeLayout
            android:id="@+id/rl_back_right"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="end"
            android:layout_marginLeft="-65dp"
            android:background="#fd5031"></RelativeLayout>
    </android.support.v4.widget.DrawerLayout>
</LinearLayout>

2.item_page2.xml

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center"
        android:textSize="18sp" />

    <movie.bw.com.douyinbofang.widget.MyVideoPlayer
        android:id="@+id/mp_video"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

3.item_video.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center"
        android:textSize="18sp" />

    <movie.bw.com.douyinbofang.widget.MyVideoPlayer
        android:id="@+id/mp_video"
        android:layout_width="match_parent"
        android:layout_height="500dp" />

</LinearLayout>

4.jz_layout_standard.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/black"
    android:descendantFocusability="blocksDescendants">

    <FrameLayout
        android:id="@+id/surface_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </FrameLayout>

    <ImageView
        android:id="@+id/thumb"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:background="#000000"
        android:scaleType="fitCenter" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone">

        <LinearLayout
            android:id="@+id/layout_bottom"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_alignParentBottom="true"
            android:background="@drawable/jz_bottom_bg"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:visibility="invisible">

            <TextView
                android:id="@+id/current"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="14dp"
                android:text="00:00"
                android:textColor="#ffffff" />

            <SeekBar
                android:id="@+id/bottom_seek_progress"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_weight="1.0"
                android:background="@null"
                android:max="100"
                android:maxHeight="1dp"
                android:minHeight="1dp"
                android:paddingBottom="8dp"
                android:paddingLeft="12dp"
                android:paddingRight="12dp"
                android:paddingTop="8dp"
                android:progressDrawable="@drawable/jz_bottom_seek_progress"
                android:thumb="@drawable/jz_bottom_seek_thumb" />

            <TextView
                android:id="@+id/total"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="00:00"
                android:textColor="#ffffff" />

            <TextView
                android:id="@+id/clarity"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:clickable="true"
                android:paddingLeft="20dp"
                android:text="clarity"
                android:textAlignment="center"
                android:textColor="#ffffff" />

            <ImageView
                android:id="@+id/fullscreen"
                android:layout_width="52.5dp"
                android:layout_height="fill_parent"
                android:paddingLeft="14dp"
                android:paddingRight="14dp"
                android:scaleType="centerInside"
                android:src="@drawable/jz_enlarge" />
        </LinearLayout>
    </LinearLayout>

    <ProgressBar
        android:id="@+id/bottom_progress"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="1.5dp"
        android:layout_alignParentBottom="true"
        android:max="100"
        android:progressDrawable="@drawable/jz_bottom_progress" />

    <ImageView
        android:id="@+id/back_tiny"
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:layout_marginLeft="6dp"
        android:layout_marginTop="6dp"
        android:background="@drawable/jz_click_back_tiny_selector"
        android:visibility="gone" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:visibility="gone">

        <RelativeLayout
            android:id="@+id/layout_top"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_alignParentTop="true"
            android:background="@drawable/jz_title_bg"
            android:gravity="center_vertical">

            <ImageView
                android:id="@+id/back"
                android:layout_width="23dp"
                android:layout_height="match_parent"
                android:layout_alignParentLeft="true"
                android:layout_alignParentStart="true"
                android:layout_alignParentTop="true"
                android:paddingLeft="12dp"
                android:paddingStart="12dp"
                android:scaleType="centerInside"
                android:src="@drawable/jz_click_back_selector" />


            <TextView
                android:id="@+id/title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginEnd="12dp"
                android:layout_marginLeft="12dp"
                android:layout_marginRight="12dp"
                android:layout_marginStart="12dp"
                android:layout_toEndOf="@+id/back"
                android:layout_toLeftOf="@+id/battery_time_layout"
                android:layout_toRightOf="@+id/back"
                android:ellipsize="end"
                android:maxLines="2"
                android:textColor="#ffffff"
                android:textSize="18sp" />

            <LinearLayout
                android:id="@+id/battery_time_layout"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentEnd="true"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:layout_marginEnd="14dp"
                android:layout_marginRight="14dp"
                android:gravity="center_vertical"
                android:orientation="vertical">

                <ImageView
                    android:id="@+id/battery_level"
                    android:layout_width="23dp"
                    android:layout_height="10dp"
                    android:layout_gravity="center_horizontal"
                    android:background="@drawable/jz_battery_level_10" />

                <TextView
                    android:id="@+id/video_current_time"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_horizontal"
                    android:gravity="center_vertical"
                    android:maxLines="1"
                    android:textColor="#ffffffff"
                    android:textSize="12.0sp" />
            </LinearLayout>

        </RelativeLayout>
    </LinearLayout>

    <ProgressBar
        android:id="@+id/loading"
        android:layout_width="@dimen/jz_start_button_w_h_normal"
        android:layout_height="@dimen/jz_start_button_w_h_normal"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:indeterminateDrawable="@drawable/jz_loading"
        android:visibility="invisible" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:visibility="gone">

        <LinearLayout
            android:id="@+id/start_layout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_gravity="center_vertical">

            <ImageView
                android:id="@+id/start"
                android:layout_width="@dimen/jz_start_button_w_h_normal"
                android:layout_height="@dimen/jz_start_button_w_h_normal"
                android:src="@drawable/jz_click_play_selector" />
        </LinearLayout>

        <TextView
            android:id="@+id/replay_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/start_layout"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="6dp"
            android:text="@string/replay"
            android:textColor="#ffffff"
            android:textSize="12sp"
            android:visibility="invisible" />


        <LinearLayout
            android:id="@+id/retry_layout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:gravity="center_horizontal"
            android:orientation="vertical">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/video_loading_faild"
                android:textColor="@android:color/white"
                android:textSize="14sp" />

            <TextView
                android:id="@+id/retry_btn"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="15dp"
                android:background="@drawable/retry_bg"
                android:paddingBottom="4dp"
                android:paddingLeft="9dp"
                android:paddingRight="9dp"
                android:paddingTop="4dp"
                android:text="@string/click_to_restart"
                android:textColor="@android:color/white"
                android:textSize="14sp" />
        </LinearLayout>
    </LinearLayout>

    <RelativeLayout
        android:id="@+id/rl_touch_help"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:alpha="0"
        android:background="#f0f2f7"></RelativeLayout>

    <LinearLayout
        android:id="@+id/ll_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:padding="15dp"
        android:visibility="gone">

        <ImageView
            android:id="@+id/iv_start"
            android:layout_width="16dp"
            android:layout_height="18dp"
            android:background="@mipmap/stop" />
    </LinearLayout>
</RelativeLayout>

这里面有自定义的东西,所以要改变路径名

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值