类似快手短视频播放器

导入依赖(app的gradle里面)

dependencies {
    ...
    implementation 'com.shuyu:GSYVideoPlayer:8.1.1'

//间隔线
    implementation 'com.yanyusong.y_divideritemdecoration:y_divideritemdecoration:2.0'
    //刷新框架
    implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0'
}

1.先创建视频资源文件

package com.example.zoukao1.video;

public class TestDataVideo {
    public static String[] videoUrls = {
            "https://txmov2.a.yximgs.com/upic/2021/01/12/15/BMjAyMTAxMTIxNTI5NDZfMjI2MTM5MzBfNDIyNjA5MTg5NjJfMV8z_b_B30ec7ad328493ab683c38a3bfd71e25e.mp4?tag=1-1610612151-xpcwebfeatured-0-biuep1oneh-5b3cbdad2bf52410&clientCacheKey=3xabkjs98yusiua_b.mp4&tt=b&di=da438c43&bp=10004",
            "https://txmov2.a.yximgs.com/upic/2021/01/07/14/BMjAyMTAxMDcxNDI3MjJfMTg1NTE1MzQzMV80MjAwNDYwNDE1NV8xXzM=_b_B849e5ede721eff26116c4a419979b1b9.mp4?tag=1-1610612008-xpcwebfeatured-0-yzxwcnifnh-17e1b12844b9cd71&clientCacheKey=3xambmkzn945n74_b.mp4&tt=b&di=da438c43&bp=10004",
            "https://txmov2.a.yximgs.com/upic/2021/01/13/19/BMjAyMTAxMTMxOTAwMTlfMTE1NTgyNjk3XzQyMzIwMDQ4Njg2XzFfMw==_b_Bfe7626e02f543c8df8bbf9a413a35bb4.mp4?tag=1-1610612008-xpcwebfeatured-0-9zd5ylk9aa-a67d6542c7e9c85c&clientCacheKey=3xfb2f59y6m3i8q_b.mp4&tt=b&di=da438c43&bp=10004",
            "https://txmov2.a.yximgs.com/upic/2019/03/29/22/BMjAxOTAzMjkyMjU1MThfMTY3NDIzNzc3XzExNzc0OTM0NDMxXzJfMw==_b_Bc454d632fa368b2384a853460175b545.mp4",
            "https://txmov2.a.yximgs.com/upic/2018/02/28/22/BMjAxODAyMjgyMjA4NTRfMTY3NDIzNzc3XzUyNzM0ODQ0MjNfMl8z_b_B7627b9efe2f9921e81222604ec335108.mp4",
            "https://txmov2.a.yximgs.com/upic/2018/07/22/22/BMjAxODA3MjIyMjAxNThfMTY3NDIzNzc3XzcyNDg5NzAzMTRfMl8z_b_B7ea40cd6fc9e20e76f0b2a95bf8fc56d.mp4",
            "https://txmov2.a.yximgs.com/upic/2018/07/29/20/BMjAxODA3MjkyMDU4MTRfMTY3NDIzNzc3XzczNTMzMTcwNDRfMl8z_b_Bf0713475f2c9558dd6bfa494e208cc3b.mp4",
            "https://txmov2.a.yximgs.com/upic/2019/02/01/22/BMjAxOTAyMDEyMjIzMTRfMTY3NDIzNzc3XzEwMzI5MzI2ODkwXzJfMw==_b_Bb9e910c9f285c3232d6c626371749901.mp4",
            "https://txmov2.a.yximgs.com/upic/2019/02/01/22/BMjAxOTAyMDEyMjU5MDVfMTY3NDIzNzc3XzEwMzMwMDM5ODE3XzJfMw==_b_B6b6f43204cc61ffd0d48cd2aa31634f6.mp4",
            "https://txmov2.a.yximgs.com/upic/2019/02/17/21/BMjAxOTAyMTcyMTUyMDZfMTY3NDIzNzc3XzEwODMyNzgyMjU2XzJfMw==_b_Bea3dc26569d5a6868f912d3d2bc8e71e.mp4",
            "https://txmov2.a.yximgs.com/upic/2019/02/17/22/BMjAxOTAyMTcyMjM2MjZfMTY3NDIzNzc3XzEwODM0MTA2MDUzXzJfMw==_b_B1b5e6425d7bebb41778843db9286ca56.mp4",
            "https://txmov2.a.yximgs.com/upic/2019/02/17/23/BMjAxOTAyMTcyMzAxMDNfMTY3NDIzNzc3XzEwODM0NjQ3NzkxXzJfMw==_b_Beb2e1669311c5f74a56e507d2ab65497.mp4",
            "https://txmov2.a.yximgs.com/upic/2019/03/02/20/BMjAxOTAzMDIyMDAwNTdfMTY3NDIzNzc3XzExMTI2OTc3NjIxXzJfMw==_b_B8ba7f313b408e5c8c1a13218022218bf.mp4",
            "https://txmov2.a.yximgs.com/upic/2019/03/31/23/BMjAxOTAzMzEyMzAzMzJfMTY3NDIzNzc3XzExODM3MjEzNzk0XzJfMw==_b_Bde1e75a25bf384044b215533b39912e1.mp4",
    };
}

2.创建视频适配器

package com.example.zoukao1.video;

import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.example.zoukao1.R;
import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer;

import java.util.List;

public class VideoAdapter extends BaseQuickAdapter<String, BaseViewHolder> {
    public VideoAdapter(@Nullable List<String> data) {
        super(R.layout.item_video, data);
    }

    @Override
    protected void convert(BaseViewHolder helper, String item) {

    }
    public void play(int position, RecyclerView recyclerView){
        StandardGSYVideoPlayer gsyVideoPlayer = (StandardGSYVideoPlayer) getViewByPosition(recyclerView,position, R.id.item_video);
        gsyVideoPlayer.setUp(getData().get(position),false,"");
        gsyVideoPlayer.setLooping(true);
        gsyVideoPlayer.startPlayLogic();
    }
    public void release(int position, RecyclerView recyclerView){
        StandardGSYVideoPlayer gsyVideoPlayer = (StandardGSYVideoPlayer) getViewByPosition(recyclerView,position, R.id.item_video);
        gsyVideoPlayer.release();
    }
    public void stop(int position,RecyclerView recyclerView){
        StandardGSYVideoPlayer gsyVideoPlayer = (StandardGSYVideoPlayer) getViewByPosition(recyclerView,position, R.id.item_video);
        gsyVideoPlayer.onVideoPause();
    }
}

懒加载

package com.example.lib2.mvp.view;

import com.example.lib2.mvp.presenter.IPresenter;

public abstract class LazyFragment<P extends IPresenter> extends BaseFragment {

    private boolean isRunResume=false;

    @Override
    public void onResume() {
        super.onResume();
        if (!isRunResume){
            lazy();
        }
        isRunResume=true;
    }

    protected abstract void lazy() ;
}

3.创建布局管理

package com.example.zoukao1.video;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.PagerSnapHelper;
import androidx.recyclerview.widget.RecyclerView;

import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE;

public class PagerLinearLayoutManager extends LinearLayoutManager implements RecyclerView.OnChildAttachStateChangeListener {
    private PagerSnapHelper snapHelper;
    public PagerLinearLayoutManager(Context context) {
        super(context);
    }

    public PagerLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    public PagerLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public void onScrollStateChanged(int state) {
        super.onScrollStateChanged(state);
        if (state==SCROLL_STATE_IDLE){
            View snapView = snapHelper.findSnapView(this);
            if (itemChangeListener!=null){
                itemChangeListener.select(getPosition(snapView),getPosition(snapView)==getItemCount()-1);
            }
        }
    }

    @Override
    public void onAttachedToWindow(RecyclerView view) {
        super.onAttachedToWindow(view);
        if (snapHelper==null){
            snapHelper=new PagerSnapHelper();
        }
        snapHelper.attachToRecyclerView(view);
        view.addOnChildAttachStateChangeListener(this);
    }

    private OnItemChangeListener itemChangeListener;

    public PagerLinearLayoutManager setOnItemChangeListener(OnItemChangeListener itemChangeListener) {
        this.itemChangeListener = itemChangeListener;
        return this;
    }

    @Override
    public void onChildViewAttachedToWindow(@NonNull View view) {
        if (itemChangeListener!=null&&getChildCount()==1){
            itemChangeListener.init(getPosition(view));
        }
    }

    @Override
    public void onChildViewDetachedFromWindow(@NonNull View view) {
        if (itemChangeListener!=null){
            itemChangeListener.relese(getPosition(view));
        }
    }

    public interface OnItemChangeListener{
        void select(int position ,boolean isLoad);
        void relese(int posotion);
        void init(int position);
        void pause(int position);
    }
}

4.fragment或activity里代码(这里用的是MVP模式)

package com.example.zoukao1;


import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;

import com.example.lib2.mvp.presenter.IPresenter;
import com.example.lib2.mvp.view.LazyFragment;
import com.example.zoukao1.video.PagerLinearLayoutManager;
import com.example.zoukao1.video.TestDataVideo;
import com.example.zoukao1.video.VideoAdapter;

import java.util.Arrays;
import java.util.List;


/**
 * A simple {@link Fragment} subclass.
 */
public class TwoFragment extends LazyFragment<IPresenter> implements PagerLinearLayoutManager.OnItemChangeListener {


    private RecyclerView rv;
    private VideoAdapter videoAdapter;
    private int num;

    @Override
    public int bindLayout() {
        return R.layout.fragment_two;
    }

    @Override
    public void initView() {

        rv = (RecyclerView) findViewById(R.id.rv);
        rv.setLayoutManager(new PagerLinearLayoutManager(getActivity()).setOnItemChangeListener(this));
    }

    @Override
    public void initData() {

    }
    public void initadapter(List<String> urls){
        if (videoAdapter==null){
            videoAdapter=new VideoAdapter(urls);
            rv.setAdapter(videoAdapter);
        }else {
            videoAdapter.getData().addAll(urls);
            videoAdapter.notifyDataSetChanged();
        }
    }

    @Override
    public void showToast(String s) {

    }

    @Override
    public void select(int position, boolean isLoad) {
        num=position;
        videoAdapter.play(position,rv);
    }

    @Override
    public void relese(int posotion) {
        num=posotion;
        videoAdapter.release(posotion,rv);
    }

    @Override
    public void init(int position) {
        num=position;
        videoAdapter.play(position,rv);
    }

    @Override
    public void pause(int position) {
        num=position;
        videoAdapter.stop(position,rv);
    }

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

    @Override
    public void onPause() {
        super.onPause();
        pause(num);
    }

    @Override
    protected void lazy() {
        initadapter(Arrays.asList(TestDataVideo.videoUrls));
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值