赞
踩
年代久远 , 建议参考github上的Demo实现方式,
链接
先放效果图
两个视频的地址:
- private final String mp4_a = "http://vfx.mtime.cn/Video/2019/03/19/mp4/190319212559089721.mp4";//玩具总动员
- private final String mp4_b = "http://vfx.mtime.cn/Video/2019/03/13/mp4/190313094901111138.mp4"; //抓小偷
我的build.gradle版本
- compileSdkVersion 29
- buildToolsVersion "29.0.0"
- defaultConfig {
- applicationId "com.klod.t1"
- minSdkVersion 21
- targetSdkVersion 29
- versionCode 1
- versionName "1.0"
- testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
- }
使用GSYVideoPlayer
- //完整版引入
- implementation 'com.shuyu:GSYVideoPlayer:7.0.1'
- implementation 'com.shuyu:gsyVideoPlayer-java:7.0.1'
实现上下滑自动播放视频只要一个Activity (先放主要代码,全部代码会在最下方给出)
1.layout只有一个RecyclerView 代码就不贴出了
2.设置RecyclerView
- private void init() {
-
- recyclerView = findViewById(R.id.video_list);
-
- List_Video_Adapter list_video_adapter = new List_Video_Adapter(this, list);
- LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
-
- //获取屏幕宽高
- DisplayMetrics dm = new DisplayMetrics();
- getWindowManager().getDefaultDisplay().getMetrics(dm);
- //自定播放帮助类 限定范围为屏幕一半的上下偏移180 括号里不用在意 因为是一个item一个屏幕
- scrollCalculatorHelper = new ScrollCalculatorHelper(R.id.list_video_player
- , dm.heightPixels / 2 - DpTools.dip2px(this, 180)
- , dm.heightPixels / 2 + DpTools.dip2px(this, 180));
-
- //让RecyclerView有ViewPager的翻页效果
- PagerSnapHelper pagerSnapHelper = new PagerSnapHelper();
- pagerSnapHelper.attachToRecyclerView(recyclerView);
- //设置LayoutManager和Adapter
- recyclerView.setLayoutManager(linearLayoutManager);
- recyclerView.setAdapter(list_video_adapter);
- //设置滑动监听
- recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
- //第一个可见视图,最后一个可见视图
- int firstVisibleItem, lastVisibleItem;
-
- @Override
- public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
- super.onScrollStateChanged(recyclerView, newState);
-
- //如果newState的状态==RecyclerView.SCROLL_STATE_IDLE;
- //播放对应的视频
- scrollCalculatorHelper.onScrollStateChanged(recyclerView, newState);
-
- }
-
- @Override
- public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
- super.onScrolled(recyclerView, dx, dy);
- firstVisibleItem = linearLayoutManager.findFirstVisibleItemPosition();
- lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
- Log.e("有几个item", firstVisibleItem + " " + lastVisibleItem);
- //一屏幕显示一个item 所以固定1
- //实时获取设置 当前显示的GSYBaseVideoPlayer的下标
- scrollCalculatorHelper.onScroll(recyclerView, firstVisibleItem, lastVisibleItem, 1);
-
- }
-
- });
-
-
- }
3. 第2步里的scrollCalculatorHelper 是GSYVideoPlayer里的一个工具类 直接复制拿来用就行
- package com.klod.t1.utils;
-
- import android.app.AlertDialog;
- import android.content.Context;
- import android.content.DialogInterface;
- import android.graphics.Rect;
- import android.os.Handler;
- import android.util.Log;
- import android.widget.Toast;
-
- import androidx.recyclerview.widget.RecyclerView;
-
- import com.shuyu.gsyvideoplayer.utils.NetworkUtils;
- import com.shuyu.gsyvideoplayer.video.base.GSYBaseVideoPlayer;
-
- /**
- * 计算滑动,自动播放的帮助类
- * Created by guoshuyu on 2017/11/2.
- */
-
- public class ScrollCalculatorHelper {
-
- private int firstVisible = 0;
- private int lastVisible = 0;
- private int visibleCount = 0;
- private int playId;
- private int rangeTop;
- private int rangeBottom;
- private PlayRunnable runnable;
-
- private final String TAG = "ScrollCalculatorHelper";
-
- private Handler playHandler = new Handler();
-
- public ScrollCalculatorHelper(int playId, int rangeTop, int rangeBottom) {
- this.playId = playId;
- this.rangeTop = rangeTop;
- this.rangeBottom = rangeBottom;
- }
-
- public void onScrollStateChanged(RecyclerView view, int scrollState) {
- switch (scrollState) {
- case RecyclerView.SCROLL_STATE_IDLE:
- Log.e(TAG,"自动播放执行");
- playVideo(view);
- break;
- }
- }
-
- public void onScroll(RecyclerView view, int firstVisibleItem, int lastVisibleItem, int visibleItemCount) {
- if (firstVisible == firstVisibleItem) {
- return;
- }
- firstVisible = firstVisibleItem;
- lastVisible = lastVisibleItem;
- visibleCount = visibleItemCount;
- }
-
-
- private void playVideo(RecyclerView view) {
-
- if (view == null) {
- return;
- }
-
- RecyclerView.LayoutManager layoutManager = view.getLayoutManager();
-
- GSYBaseVideoPlayer gsyBaseVideoPlayer = null;
-
- boolean needPlay = false;
- Log.e(TAG,"自动播放执行 View未空"+visibleCount);
- for (int i = 0; i < visibleCount; i++) {
- if (layoutManager.getChildAt(i) != null && layoutManager.getChildAt(i).findViewById(playId) != null) {
- GSYBaseVideoPlayer player = layoutManager.getChildAt(i).findViewById(playId);
- Rect rect = new Rect();
- player.getLocalVisibleRect(rect);
- int height = player.getHeight();
- //说明第一个完全可视
- if (rect.top == 0 && rect.bottom == height) {
- gsyBaseVideoPlayer = player;
- if ((player.getCurrentPlayer().getCurrentState() == GSYBaseVideoPlayer.CURRENT_STATE_NORMAL
- || player.getCurrentPlayer().getCurrentState() == GSYBaseVideoPlayer.CURRENT_STATE_ERROR)) {
- needPlay = true;
- }
- break;
- }
-
- }
-
- }
-
-
- if (gsyBaseVideoPlayer != null && needPlay) {
- if (runnable != null) {
- GSYBaseVideoPlayer tmpPlayer = runnable.gsyBaseVideoPlayer;
- playHandler.removeCallbacks(runnable);
- runnable = null;
- if (tmpPlayer == gsyBaseVideoPlayer) {
- return;
- }
- }
- Log.e(TAG,"自动播放执行 开始");
- runnable = new PlayRunnable(gsyBaseVideoPlayer);
- //降低频率
- playHandler.postDelayed(runnable, 400);
- }
-
-
- }
-
- private class PlayRunnable implements Runnable {
-
- GSYBaseVideoPlayer gsyBaseVideoPlayer;
-
- public PlayRunnable(GSYBaseVideoPlayer gsyBaseVideoPlayer) {
- this.gsyBaseVideoPlayer = gsyBaseVideoPlayer;
- }
-
- @Override
- public void run() {
- boolean inPosition = false;
- //如果未播放,需要播放
- if (gsyBaseVideoPlayer != null) {
- int[] screenPosition = new int[2];
- gsyBaseVideoPlayer.getLocationOnScreen(screenPosition);
- int halfHeight = gsyBaseVideoPlayer.getHeight() / 2;
- int rangePosition = screenPosition[1] + halfHeight;
- //中心点在播放区域内
- if (rangePosition >= rangeTop && rangePosition <= rangeBottom) {
- inPosition = true;
- }
- if (inPosition) {
- startPlayLogic(gsyBaseVideoPlayer, gsyBaseVideoPlayer.getContext());
- //gsyBaseVideoPlayer.startPlayLogic();
- }
- }
- }
- }
-
-
- /***************************************自动播放的点击播放确认******************************************/
- private void startPlayLogic(GSYBaseVideoPlayer gsyBaseVideoPlayer, Context context) {
- if (!com.shuyu.gsyvideoplayer.utils.CommonUtil.isWifiConnected(context)) {
- //这里判断是否wifi
- showWifiDialog(gsyBaseVideoPlayer, context);
- return;
- }
- gsyBaseVideoPlayer.startPlayLogic();
- }
-
- private void showWifiDialog(final GSYBaseVideoPlayer gsyBaseVideoPlayer, Context context) {
- if (!NetworkUtils.isAvailable(context)) {
- Toast.makeText(context, context.getResources().getString(com.shuyu.gsyvideoplayer.R.string.no_net), Toast.LENGTH_LONG).show();
- return;
- }
- AlertDialog.Builder builder = new AlertDialog.Builder(context);
- builder.setMessage(context.getResources().getString(com.shuyu.gsyvideoplayer.R.string.tips_not_wifi));
- builder.setPositiveButton(context.getResources().getString(com.shuyu.gsyvideoplayer.R.string.tips_not_wifi_confirm), new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- gsyBaseVideoPlayer.startPlayLogic();
- }
- });
- builder.setNegativeButton(context.getResources().getString(com.shuyu.gsyvideoplayer.R.string.tips_not_wifi_cancel), new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- }
- });
- builder.create().show();
- }
-
- }
接下来做RecyclerView适配器
适配器的Item就一个StandardGSYVideoPlayer
xml:
- <com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
- android:id="@+id/list_video_player"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_centerVertical="true"
- android:paddingBottom="20dp"
- />
adapter:
- package com.klod.t1.adapter;
-
- import android.content.Context;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
-
- import androidx.annotation.NonNull;
- import androidx.recyclerview.widget.RecyclerView;
-
- import com.klod.t1.R;
- import com.klod.t1.bean.Video_Bean;
- import com.shuyu.gsyvideoplayer.GSYVideoManager;
- import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder;
- import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack;
- import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer;
-
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
-
- public class List_Video_Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
-
- private Context context;
- private List<Video_Bean> list;
-
- public static final String TAG = "ListNormalAdapter22";
-
- private GSYVideoOptionBuilder gsyVideoOptionBuilder;
-
-
- public List_Video_Adapter(Context context,List<Video_Bean> list) {
- this.context = context;
- this.list = list;
-
- }
-
- @NonNull
- @Override
- public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
- return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.list_video_item,parent,false));
- }
-
- @Override
- public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
-
- ViewHolder vh = (ViewHolder) holder;
-
- Map<String, String> header = new HashMap<>();
- header.put("ee", "33");
- //配置视频播放器参数
- gsyVideoOptionBuilder
- .setIsTouchWiget(false)
- .setUrl(list.get(position).getUrl())
- .setVideoTitle(list.get(position).getTitle())
- .setCacheWithPlay(false)
- .setRotateViewAuto(true)
- .setLockLand(true)
- .setPlayTag(TAG)
- .setMapHeadData(header)
- .setShowFullAnimation(true)
- .setNeedLockFull(true)
- .setPlayPosition(position)
- .setReleaseWhenLossAudio(false)
- .setVideoAllCallBack(new GSYSampleCallBack() {
- @Override
- public void onPrepared(String url, Object... objects) {
- super.onPrepared(url, objects);
- if (!vh.standardGSYVideoPlayer.isIfCurrentIsFullscreen()) {
- //静音
- //GSYVideoManager.instance().setNeedMute(true);
- }
-
- }
-
- @Override
- public void onQuitFullscreen(String url, Object... objects) {
- super.onQuitFullscreen(url, objects);
- //全屏不静音
- //GSYVideoManager.instance().setNeedMute(true);
- }
-
- @Override
- public void onEnterFullscreen(String url, Object... objects) {
- super.onEnterFullscreen(url, objects);
- GSYVideoManager.instance().setNeedMute(false);
- vh.standardGSYVideoPlayer.getCurrentPlayer().getTitleTextView().setText((String)objects[0]);
- }
- }).build(vh.standardGSYVideoPlayer);
-
- //设置返回键
- vh.standardGSYVideoPlayer.getBackButton().setVisibility(View.GONE);
-
- //设置全屏按键功能
- vh.standardGSYVideoPlayer.getFullscreenButton().setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- vh.standardGSYVideoPlayer.startWindowFullscreen(context, false, true);
- }
- });
- //实现第一个视频自动播放
- if(position==0){
- vh.standardGSYVideoPlayer.startPlayLogic();
- }
-
- }
-
- @Override
- public int getItemCount() {
- return list==null?0:list.size();
- }
-
- class ViewHolder extends RecyclerView.ViewHolder{
-
- private StandardGSYVideoPlayer standardGSYVideoPlayer;
-
- public ViewHolder(@NonNull View itemView) {
- super(itemView);
- gsyVideoOptionBuilder = new GSYVideoOptionBuilder();
- standardGSYVideoPlayer = itemView.findViewById(R.id.list_video_player);
-
- }
-
-
- }
-
- }
到这就实现了短视频软件上下滑自动播放视频
总体流程:
写布局=>写适配器=>写Activity逻辑
给出Activity全部代码:
- package com.klod.t1.activity;
-
- import android.content.res.Configuration;
- import android.os.Bundle;
- import android.util.DisplayMetrics;
- import android.util.Log;
- import android.view.WindowManager;
-
- import androidx.annotation.NonNull;
- import androidx.annotation.Nullable;
- import androidx.appcompat.app.AppCompatActivity;
- import androidx.core.content.ContextCompat;
- import androidx.recyclerview.widget.LinearLayoutManager;
- import androidx.recyclerview.widget.PagerSnapHelper;
- import androidx.recyclerview.widget.RecyclerView;
-
- import com.klod.t1.R;
- import com.klod.t1.adapter.List_Video_Adapter;
- import com.klod.t1.bean.Video_Bean;
- import com.klod.t1.utils.DpTools;
- import com.klod.t1.utils.ScrollCalculatorHelper;
- import com.klod.t1.utils.StatusBarUtil;
- import com.shuyu.gsyvideoplayer.GSYVideoManager;
-
- import java.util.ArrayList;
- import java.util.List;
-
- public class List_Video_Activity extends AppCompatActivity {
-
- private RecyclerView recyclerView;
- private final String mp4_a = "http://vfx.mtime.cn/Video/2019/03/19/mp4/190319212559089721.mp4";//玩具总动员
- private final String mp4_b = "http://vfx.mtime.cn/Video/2019/03/13/mp4/190313094901111138.mp4"; //抓小偷
- private List<Video_Bean> list;
-
- //控制滚动播放
- ScrollCalculatorHelper scrollCalculatorHelper;
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.list_video_activity);
- StatusBarUtil.setColor(this, getResources().getColor(R.color.HaiPaiBlack));
-
- initData();
- init();
-
- }
-
- private void initData() {
- //视频数据
- list = new ArrayList<>();
- for (int i = 0; i < 10; i++) {
-
- Video_Bean video_bean = new Video_Bean();
- if (i % 2 == 0) {
- video_bean.setUrl(mp4_a);
- } else {
- video_bean.setUrl(mp4_b);
- }
- video_bean.setBitmap(ContextCompat.getDrawable(this, R.drawable.image));
- video_bean.setTitle("傀儡偶段のVideo " + i);
-
- list.add(video_bean);
- }
-
- }
-
- private void init() {
-
- recyclerView = findViewById(R.id.video_list);
-
- List_Video_Adapter list_video_adapter = new List_Video_Adapter(this, list);
- LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
-
- //获取屏幕宽高
- DisplayMetrics dm = new DisplayMetrics();
- getWindowManager().getDefaultDisplay().getMetrics(dm);
- //自定播放帮助类 限定范围为屏幕一半的上下偏移180 括号里不用在意 因为是一个item一个屏幕
- scrollCalculatorHelper = new ScrollCalculatorHelper(R.id.list_video_player
- , dm.heightPixels / 2 - DpTools.dip2px(this, 180)
- , dm.heightPixels / 2 + DpTools.dip2px(this, 180));
-
- //让RecyclerView有ViewPager的翻页效果
- PagerSnapHelper pagerSnapHelper = new PagerSnapHelper();
- pagerSnapHelper.attachToRecyclerView(recyclerView);
- //设置LayoutManager和Adapter
- recyclerView.setLayoutManager(linearLayoutManager);
- recyclerView.setAdapter(list_video_adapter);
- //设置滑动监听
- recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
- //第一个可见视图,最后一个可见视图
- int firstVisibleItem, lastVisibleItem;
-
- @Override
- public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
- super.onScrollStateChanged(recyclerView, newState);
-
- //如果newState的状态==RecyclerView.SCROLL_STATE_IDLE;
- //播放对应的视频
- scrollCalculatorHelper.onScrollStateChanged(recyclerView, newState);
-
- }
-
- @Override
- public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
- super.onScrolled(recyclerView, dx, dy);
- firstVisibleItem = linearLayoutManager.findFirstVisibleItemPosition();
- lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
- Log.e("有几个item", firstVisibleItem + " " + lastVisibleItem);
- //一屏幕显示一个item 所以固定1
- //实时获取设置 当前显示的GSYBaseVideoPlayer的下标
- scrollCalculatorHelper.onScroll(recyclerView, firstVisibleItem, lastVisibleItem, 1);
-
- }
-
- });
-
-
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- GSYVideoManager.onResume();
- }
-
- @Override
- protected void onPause() {
- super.onPause();
-
- GSYVideoManager.onPause();
-
- }
- @Override
- protected void onDestroy() {
- super.onDestroy();
-
- GSYVideoManager.releaseAllVideos();
-
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
-
-
- Configuration mConfiguration = this.getResources().getConfiguration();
- int ori = mConfiguration.orientation;
- if (ori == Configuration.ORIENTATION_LANDSCAPE) {
-
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); //隐藏状态栏
-
- } else if (ori == Configuration.ORIENTATION_PORTRAIT) {
- //当前为竖屏
- getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); //显示状态栏
- }
-
- super.onConfigurationChanged(newConfig);
- }
- }
还有一个单位转换类:
- public class DpTools {
- /**
- * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
- */
- public static int dip2px(Context context, float dpValue) {
- final float scale = context.getResources().getDisplayMetrics().density;
- return (int) (dpValue * scale + 0.5f);
- }
-
- /**
- * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
- */
- public static int px2dip(Context context, float pxValue) {
- final float scale = context.getResources().getDisplayMetrics().density;
- return (int) (pxValue / scale + 0.5f);
- }
- }
补上 Bean的代码
- public class Video_Bean implements Serializable {
- /**
- * 默认
- */
- public static final long serialVersionUID = 1L;
-
- private String url;
- private String title;
- private Drawable bitmap;
-
- public Video_Bean() {
-
- }
-
- public Video_Bean(String url, String title, Drawable bitmap) {
-
- this.url = url;
- this.bitmap = bitmap;
- this.title = title;
-
- }
-
- public String getUrl() {
- return url;
- }
-
- public void setUrl(String url) {
- this.url = url;
- }
-
- public String getTitle() {
- return title;
- }
-
- public void setTitle(String title) {
- this.title = title;
- }
-
- public Drawable getBitmap() {
- return bitmap;
- }
-
- public void setBitmap(Drawable bitmap) {
- this.bitmap = bitmap;
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。