【安卓】娇子视频播放器初体验

首先先放一张最简单的视频播放图: 

 

OK,加下来开始进入正题:

一、开始集成(GitHub地址)

1.导入依赖:

//娇子播放器
//项目地址 : https://github.com/lipangit/JiaoZiVideoPlayer
implementation 'cn.jzvd:jiaozivideoplayer:7.0.5'

2.添加网络权限:

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

3.添加控件

ps:这里有一点需要注意,通常来说我们去添加一个控件的时候都是直接添加控件到对应布局,就像这样:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activity.JiaoZiVideo.JZInActivity">

    <!-- 原生娇子播放器 -->
    <cn.jzvd.JzvdStd
        android:id="@+id/jzin_video"
        android:layout_width="match_parent"
        android:layout_height="200dp" />

</LinearLayout>

但是这样做之后,实际测试中的效果是,初始进来加载布局没问题,正常显示,但是进入全屏之后再退出全屏的时候,效果是这样的:

初始化加载
退出全屏后

 

正确的做法是:在视频控件的外层在添加一层布局,将宽高写在父布局里,就像这样:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activity.JiaoZiVideo.JZInActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="200dp">

        <!-- 原生娇子播放器 -->
        <cn.jzvd.JzvdStd
            android:id="@+id/jzin_video"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </LinearLayout>

</LinearLayout>

具体是什么原因导致的这个问题目前暂无法得知,待研究....

4.设置视频地址和标题

官方文档中推荐使用的是 Glide 进行加载视频缩略图,因为我这里目前用的是Fresco,所以暂时就不写了,后期再补出来~

private JzvdStd jzin_video;
private void initView() {
        jzin_video = (JzvdStd) findViewById(R.id.jzin_video);

        //加载网络视频
     jzin_video.setUp("https://img.tukuppt.com/video_show/2402760/00/01/73/5b495ddab7660.mp4","网络视频测试");
        //加载视频缩略图
        //待完善代码
}

5.生命周期中添加基本监听

    @Override
    protected void onPause() {
        super.onPause();
        jzin_video.releaseAllVideos();
    }

    @Override
    public void onBackPressed() {
        if (jzin_video.backPress()) {
            return;
        }
        super.onBackPressed();
    }

6.在 AndroidManifest.xml 中对应的Activity添加:

android:configChanges="orientation|screenSize|keyboardHidden"
android:screenOrientation="portrait"

 

以上基本上就完成了娇子播放器的简单播放网络视频,项目中原先用的是百度播放器,对比之下娇子有很强的的优势,更加易用.

二、在列表中播放

注意,每个有视频播放的页面,只要需要全屏,其对应的 Activity 都应在 AndroidManifest.xml 中添加参数

android:configChanges="orientation|screenSize|keyboardHidden"
android:screenOrientation="portrait"

在此引用的是 RecycleView 作为列表

1.创建列表布局

<?xml version="1.0" encoding="utf-8"?>
<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.JiaoZiVideo.JZInListActivity">

    <!-- 承载视频的列表 -->
    <android.support.v7.widget.RecyclerView
        android:id="@+id/jzinList_Rec"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>

</android.support.constraint.ConstraintLayout>

2.创建条目布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="100dp">

        <!-- 顶部标题 -->
        <TextView
            android:id="@+id/item_listitem_title_txt"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:maxLines="2"
            android:textSize="16sp"
            android:textColor="#383838"
            android:textStyle="normal"
            android:layout_marginTop="5dp"
            android:layout_marginBottom="5dp"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp"/>

        <!-- 条目中视频布局 -->
        <RelativeLayout
            android:id="@+id/item_listitem_videoLayout"
            android:layout_width="wrap_content"
            android:layout_height="200dp"
            android:layout_below="@id/item_listitem_title_txt"
            android:layout_marginTop="5dp"
            android:layout_marginBottom="5dp"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp">

            <!-- 原生娇子播放器 -->
            <cn.jzvd.JzvdStd
                android:id="@+id/jzin_video_inRecList"
                android:layout_width="match_parent"
                android:layout_height="200dp" />

        </RelativeLayout>

        <!-- 来源布局 -->
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/item_listitem_videoLayout"
            android:layout_marginBottom="5dp"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp">

            <!-- 小眼睛图标 -->
            <ImageView
                android:id="@+id/item_listitem_readingVolume_img"
                android:layout_centerVertical="true"
                android:layout_width="15dp"
                android:layout_height="10dp"
                android:src="@mipmap/readingvolume"/>

            <!-- 阅读量 -->
            <TextView
                android:id="@+id/item_listitem_readingVolume"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="6dp"
                android:layout_centerVertical="true"
                android:layout_toRightOf="@id/item_listitem_readingVolume_img"
                android:textColor="#999999"
                android:textSize="10sp" />

            <!-- 来源 -->
            <TextView
                android:id="@+id/item_listitem_source"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:textColor="#999999"
                android:textSize="10sp"
                android:maxEms="8"
                android:maxLines="1"
                android:ellipsize="end"
                android:layout_marginLeft="10dp"/>

            <!-- 时间 -->
            <TextView
                android:id="@+id/item_listitem_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@id/item_listitem_readingVolume"
                android:layout_toLeftOf="@id/item_listitem_source"
                android:layout_marginLeft="8dp"
                android:layout_centerVertical="true"
                android:textColor="#999999"
                android:textSize="10sp" />

        </RelativeLayout>

    </RelativeLayout>

</LinearLayout>

3.编写适配器

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.wwgtest.goodlib.R;

import java.util.List;
import java.util.Map;

import cn.jzvd.Jzvd;
import cn.jzvd.JzvdStd;

/**
 * 作者:WWGsky on 2019/7/16 18:00
 * <p>
 * 作用: 娇子列表播放适配器
 */
public class JZInRecAdapter extends RecyclerView.Adapter<JZInRecAdapter.LinearViewHolder>{

    private Context mContext;
    private List<Map<String,String>> list;
    private OnItemClickListener itemClickListener;


    public JZInRecAdapter(Context mContext, List<Map<String,String>> data) {
        this.mContext = mContext;
        list = data;
    }

    @Override
    public JZInRecAdapter.LinearViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LinearViewHolder holder = new LinearViewHolder(LayoutInflater.from(
                mContext).inflate(R.layout.item_jzinlist_itemlayout, parent,
                false));
        return holder;
    }

    @Override
    public void onBindViewHolder(JZInRecAdapter.LinearViewHolder holder, int position) {

        //给控件赋值
        holder.item_listitem_title_txt.setText(list.get(position).get("title"));
        //在此加载视频链接
        //第一个参数是视频连接地址,第二个为标题,第三个为播放器格式,当前为标准模式
        holder.jzin_video.setUp(list.get(position).get("videoUel"),"", Jzvd.SCREEN_NORMAL);
        holder.item_listitem_readingVolume.setText(list.get(position).get("readingVolume"));
        holder.item_listitem_source.setText(list.get(position).get("source"));
        holder.item_listitem_time.setText(list.get(position).get("time"));

        //在此预设了条目的点击监听
        if (itemClickListener!=null){
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    itemClickListener.onItemClick(position);
                }
            });
        }

    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    class LinearViewHolder extends RecyclerView.ViewHolder{
        private TextView item_listitem_title_txt;
        private JzvdStd jzin_video;
        private final TextView item_listitem_readingVolume;
        private final TextView item_listitem_source;
        private final TextView item_listitem_time;

        public LinearViewHolder(View itemView){
            super(itemView);
            item_listitem_title_txt=(TextView) itemView.findViewById(R.id.item_listitem_title_txt);
            jzin_video = (JzvdStd) itemView.findViewById(R.id.jzin_video_inRecList);
            item_listitem_readingVolume = (TextView) itemView.findViewById(R.id.item_listitem_readingVolume);
            item_listitem_source = (TextView) itemView.findViewById(R.id.item_listitem_source);
            item_listitem_time = (TextView) itemView.findViewById(R.id.item_listitem_time);
        }
    }

    /**
     * 条目点击监听接口
     */
    public interface OnItemClickListener {
        void onItemClick(int position);
    }

    /**
     * 暴露给外部的条目点击监听方法
     */
    public void setOnItemClickListener(OnItemClickListener listener) {
        itemClickListener = listener;
    }

}

4.准备测试数据

Map<String,String> map1 = new HashMap<>();
        map1.put("title","多彩LED酷炫旋转视频背景");
        map1.put("videoUel","https://img.tukuppt.com/video_show/2402760/00/01/73/5b495ddab7660.mp4");
        map1.put("readingVolume","16485");
        map1.put("source","熊猫");
        map1.put("time","1小时前");

        Map<String,String> map2 = new HashMap<>();
        map2.put("title","线条描绘时间线同学会毕业相册");
        map2.put("videoUel","https://img.tukuppt.com/video_show/2629112/00/02/76/5b8ce0b65a774.mp4");
        map2.put("readingVolume","16485");
        map2.put("source","熊猫");
        map2.put("time","5小时前");

        Map<String,String> map3 = new HashMap<>();
        map3.put("title","大气水墨转场照片相册");
        map3.put("videoUel","https://img.tukuppt.com/video_show/2629112/00/03/29/5bc1fe8d802b6.mp4");
        map3.put("readingVolume","16485");
        map3.put("source","熊猫");
        map3.put("time","刚刚");

        Map<String,String> map4 = new HashMap<>();
        map4.put("title","震撼年会开场片头");
        map4.put("videoUel","https://img.tukuppt.com/video_show/2405811/00/02/45/5b65b4da72f5c.mp4");
        map4.put("readingVolume","16485");
        map4.put("source","熊猫");
        map4.put("time","一天前");

5.将数据设置到List

        jzinList_Rec = (RecyclerView) findViewById(R.id.jzinList_Rec);
        //设置线性布局
        jzinList_Rec.setLayoutManager(new LinearLayoutManager(this));

        //创建测试数据源
        List<Map<String,String>> list = new ArrayList<>();
        //添加测试数据
        list.add(map1);
        list.add(map2);
        list.add(map3);
        list.add(map4);

        //创建适配器对象
        jzInRecAdapter = new JZInRecAdapter(this, list);
        //设置适配器
        jzinList_Rec.setAdapter(jzInRecAdapter);

6.添加条目复用监听

//添加条目复用监听
        jzinList_Rec.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() {
            @Override
            public void onChildViewAttachedToWindow(View view) {

            }

            @Override
            public void onChildViewDetachedFromWindow(View view) {
                Jzvd jzvd = view.findViewById(R.id.jzin_video_inRecList);
                if (jzvd != null && Jzvd.CURRENT_JZVD != null &&
                        jzvd.jzDataSource.containsTheUrl(Jzvd.CURRENT_JZVD.jzDataSource.getCurrentUrl())) {
                    if (Jzvd.CURRENT_JZVD != null && Jzvd.CURRENT_JZVD.screen != Jzvd.SCREEN_FULLSCREEN) {
                        Jzvd.releaseAllVideos();
                    }
                }
            }
        });

7.添加基本生命周期监听

@Override
    public void onBackPressed() {
        if (Jzvd.backPress()) {
            return;
        }
        super.onBackPressed();
    }

    @Override
    protected void onPause() {
        super.onPause();
        Jzvd.releaseAllVideos();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                finish();
                break;
        }
        return super.onOptionsItemSelected(item);
    }

完整 Activity :

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.MenuItem;
import android.view.View;

import com.wwgtest.goodlib.R;
import com.wwgtest.goodlib.adapter.JZInRecAdapter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.jzvd.Jzvd;

/**
 * 娇子播放器-在列表中展示
 */
public class JZInListActivity extends AppCompatActivity {

    private RecyclerView jzinList_Rec;
    private JZInRecAdapter jzInRecAdapter;

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

    private void initView() {
        jzinList_Rec = (RecyclerView) findViewById(R.id.jzinList_Rec);
        //设置线性布局
        jzinList_Rec.setLayoutManager(new LinearLayoutManager(this));

        //创建测试数据源
        List<Map<String,String>> list = new ArrayList<>();

        Map<String,String> map1 = new HashMap<>();
        map1.put("title","多彩LED酷炫旋转视频背景");
        map1.put("videoUel","https://img.tukuppt.com/video_show/2402760/00/01/73/5b495ddab7660.mp4");
        map1.put("readingVolume","16485");
        map1.put("source","熊猫");
        map1.put("time","1小时前");

        Map<String,String> map2 = new HashMap<>();
        map2.put("title","线条描绘时间线同学会毕业相册");
        map2.put("videoUel","https://img.tukuppt.com/video_show/2629112/00/02/76/5b8ce0b65a774.mp4");
        map2.put("readingVolume","16485");
        map2.put("source","熊猫");
        map2.put("time","5小时前");

        Map<String,String> map3 = new HashMap<>();
        map3.put("title","大气水墨转场照片相册");
        map3.put("videoUel","https://img.tukuppt.com/video_show/2629112/00/03/29/5bc1fe8d802b6.mp4");
        map3.put("readingVolume","16485");
        map3.put("source","熊猫");
        map3.put("time","刚刚");

        Map<String,String> map4 = new HashMap<>();
        map4.put("title","震撼年会开场片头");
        map4.put("videoUel","https://img.tukuppt.com/video_show/2405811/00/02/45/5b65b4da72f5c.mp4");
        map4.put("readingVolume","16485");
        map4.put("source","熊猫");
        map4.put("time","一天前");

        //添加测试数据
        list.add(map1);
        list.add(map2);
        list.add(map3);
        list.add(map4);

        //创建适配器对象
        jzInRecAdapter = new JZInRecAdapter(this, list);
        //设置适配器
        jzinList_Rec.setAdapter(jzInRecAdapter);
        //添加条目复用监听
        jzinList_Rec.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() {
            @Override
            public void onChildViewAttachedToWindow(View view) {

            }

            @Override
            public void onChildViewDetachedFromWindow(View view) {
                Jzvd jzvd = view.findViewById(R.id.jzin_video_inRecList);
                if (jzvd != null && Jzvd.CURRENT_JZVD != null &&
                        jzvd.jzDataSource.containsTheUrl(Jzvd.CURRENT_JZVD.jzDataSource.getCurrentUrl())) {
                    if (Jzvd.CURRENT_JZVD != null && Jzvd.CURRENT_JZVD.screen != Jzvd.SCREEN_FULLSCREEN) {
                        Jzvd.releaseAllVideos();
                    }
                }
            }
        });
    }

    @Override
    public void onBackPressed() {
        if (Jzvd.backPress()) {
            return;
        }
        super.onBackPressed();
    }

    @Override
    protected void onPause() {
        super.onPause();
        Jzvd.releaseAllVideos();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                finish();
                break;
        }
        return super.onOptionsItemSelected(item);
    }
}

 

三、圆角播放器

 

 

 

四、自定义UI

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WWGtest

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值