关于安卓viewpager播放视频实现

简介: 安卓viewpager播放视频

废话不多说:

代码地址在文末

思路

通过监听vp的滑动位置,以及vp对应位置的root view,以代码动态添加,移除的方式,实现videoview的插入与移除,实现播放功能。

实现:

(一) 动态通过代码,实现videoview的添加和移除,达到播放视频逻辑

--因为videoview在布局中直接使用,会直接持有了activity的对象导致内存泄漏,所以通过代码动态添加来实现。

   /**
     * 创建video view
     */
    public VideoView Builder(Context context, ViewGroup mPlayerRoot) {
        Context applicationContext = context.getApplicationContext();
        VideoView mPlayView = new VideoView(applicationContext);
        mPlayerRoot.addView(mPlayView);
        ViewGroup.LayoutParams params = mPlayView.getLayoutParams();
        params.width = LinearLayout.LayoutParams.MATCH_PARENT;
        params.height = LinearLayout.LayoutParams.MATCH_PARENT;
        mPlayView.setLayoutParams(params);
        MediaController mediaController = new MediaController(context);
        mediaController.setVisibility(View.INVISIBLE);
        mPlayView.setMediaController(mediaController);
        return mPlayView;
    }

    /**
     * 释放video view
     */
    public void releaseVideoView(VideoView mPlayView) {
        try {
            mPlayView.stopPlayback();
            mPlayView.suspend();
            mPlayView.setOnErrorListener(null);
            mPlayView.setOnPreparedListener(null);
            mPlayView.setOnCompletionListener(null);
            mPlayView.setMediaController(null);
        } catch (Exception e) {

        }
    }

(二)重写viewpager,回调vp的旧位置,新位置。该位置信息用于后续移除对于位置的videoview。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VYraU3VJ-1648365008819)(https://upload-images.jianshu.io/upload_images/13738977-8e42d7acf5f38120.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]

(三)自定义videoview

通过自定义的videoview,可以定义设计稿上面的相关控件。这里使用的是代码动态添加view的方式。当然还可以自定义一个xml插入,这里就不过多叙述。要注意的是,videoview的添加or移除需要以代码的形式。核心代码如下:

    /**
     * add view
     */
    public void addToParent(LinearLayout root) {
        root.removeAllViews();
        root.addView(this);
        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) this.getLayoutParams();
        params.width = LinearLayout.LayoutParams.MATCH_PARENT;
        params.height = LinearLayout.LayoutParams.MATCH_PARENT;
        setLayoutParams(params);
        //在把video view添加到该view
        mPlayView = VideoBuilder.getInstance().Builder(getContext(), this);
        RelativeLayout.LayoutParams layoutParams = (LayoutParams) mPlayView.getLayoutParams();
        layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
        mPlayView.setLayoutParams(layoutParams);
        //把播放按钮设置到view
        mPlayBt = new ImageView(getContext());
        addView(mPlayBt);
        RelativeLayout.LayoutParams btLayoutParams = (LayoutParams) mPlayBt.getLayoutParams();
        btLayoutParams.width = 80;
        btLayoutParams.height = 80;
        btLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
        mPlayBt.setLayoutParams(btLayoutParams);
        //设置默认图片
        mPlayBt.setImageResource(mPlayRes);

        //监听事件---------------------------------------------------------------------------------
        mPlayView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            @Override
            public boolean onError(MediaPlayer mp, int what, int extra) {
                mPlayProgress = 0;
                updatePlayUI(false);
                return true;
            }
        });
        mPlayView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                mPlayProgress = 0;
                updatePlayUI(false);
            }
        });
        mPlayBt.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mPlayView == null) {
                    return;
                }
                if (mPlayView.isPlaying()) {
                    mPlayView.pause();
                    mPlayProgress = mPlayView.getCurrentPosition();
                    updatePlayUI(false);
                }else{
                    mPlayView.seekTo(mPlayProgress);
                    mPlayView.start();
                    updatePlayUI(true);
                }
            }
        });
    }

(四)调用

调用就相对简单了,监听到播放的事件后,直接new一个自定义videoview的对象,然后插入对应的vp布局。再者,当vp从当前位置滑动后,移除相关的view。而对于vp的布局对象,可以用一个list缓存,当界面销毁的时候,记得及时移除,不然会导致内存泄漏。调用代码如下:

package com.north.light.androidutils.viewpagervideo;

import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.VideoView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.PagerAdapter;

import com.north.light.androidutils.R;
import com.north.light.androidutils.log.LogUtil;

import org.jetbrains.annotations.NotNull;

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

/**
 * viewpager播放video
 */
public class ViewPagerVideoActivity extends AppCompatActivity {
    private CusViewPager page1;
    private Map<Integer, LinearLayout> viewMap = new HashMap<>();

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

    @Override
    protected void onDestroy() {
        super.onDestroy();

    }

    private void init() {

        List<View> viewList = new ArrayList<>();
        for (int i = 0; i < 12; i++) {
            View cacheView = View.inflate(ViewPagerVideoActivity.this, R.layout.viewpager_item, null);
            viewList.add(cacheView);
        }
        CusPagerAdapter adapter = new CusPagerAdapter(ViewPagerVideoActivity.this, viewList);
        page1 = findViewById(R.id.activity_view_pager_video_content);
        page1.setAdapter(adapter);
        page1.setPageListener(new CusViewPager.PageListener() {
            @Override
            public void pageChange(int oldPos, int newPos) {
                LogUtil.d("pageChange old pos:" + oldPos + " new pos:" + newPos);
                LinearLayout root = viewMap.get(oldPos);
                if (root == null) {
                    return;
                }
                root.removeAllViews();
            }
        });
    }

    private class CusPagerAdapter extends PagerAdapter {
        private Context context;
        private List<View> viewList = new ArrayList<>();

        public CusPagerAdapter(Context context, List<View> viewList) {
            this.context = context;
            this.viewList = viewList;
        }

        @Override
        public int getCount() {
            return viewList.size();
        }


        @Override
        public boolean isViewFromObject(@NonNull @NotNull View view, @NonNull @NotNull Object object) {
            return view == object;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            viewMap.remove(position);
            container.removeView((View) object);
        }

        @NotNull
        @Override
        public Object instantiateItem(@NonNull @NotNull ViewGroup container, int position) {
            View root = viewList.get(position);
            container.addView(root);
            TextView tx = root.findViewById(R.id.viewpager_item_tx);
            LinearLayout mVideoRoot = root.findViewById(R.id.viewpager_item_video_root);
            tx.setText(String.valueOf(position));
            viewMap.put(position, mVideoRoot);
            tx.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (position == 1) {
                        tx.setBackgroundColor(getResources().getColor(R.color.colorAccent));
                    } else if (position == 2) {
                        tx.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark));
                    } else if (position == 3) {
                        tx.setBackgroundColor(getResources().getColor(R.color.color_F06091));
                    } else if (position == 4) {
                        tx.setBackgroundColor(getResources().getColor(R.color.color_a8a8a8));
                    } else {
                        tx.setBackgroundColor(getResources().getColor(R.color.blue_light));
                    }
                    dealClickInfo(position);
                }
            });
            return viewList.get(position);
        }
    }

    /**
     * 处理点击事件
     */
    private void dealClickInfo(int position) {
        LinearLayout root = viewMap.get(position);
        if (root == null) {
            return;
        }
        CusVideoView videoView = new CusVideoView(this);
        videoView.setPlayRes(R.mipmap.ic_heart1,R.mipmap.ic_heart_sel);
        videoView.addToParent(root);
        if (position % 2 == 1) {
            String path1 = Environment.getExternalStorageDirectory().getPath() +
                    "/DCIM/Camera/share_893adea390ed3b7a0f2da1223092a3ef.mp4";
            videoView.play(path1);
        } else if (position % 2 == 0) {
            String path2 = Environment.getExternalStorageDirectory().getPath() +
                    "/DCIM/Camera/share_adb4ba0e521ba0003e0ab7ca98843738.mp4";
            videoView.play(path2);
        } else {
            String path3 = Environment.getExternalStorageDirectory().getPath() +
                    "/DCIM/Camera/share_adb4ba0e521ba0003e0ab7ca98843738.mp4";
            videoView.play(path3);
        }
    }
}

代码地址

that's all----------------------------------------------------------------------------------

目录
相关文章
|
4月前
|
XML Java Android开发
Android Studio App开发之翻页视图ViewPager的讲解及实战(附源码 包括翻页视图和翻页标签栏)
Android Studio App开发之翻页视图ViewPager的讲解及实战(附源码 包括翻页视图和翻页标签栏)
105 0
|
8月前
|
Android开发
Android 使用ViewPager实现手动左右切换页面和底部点点跟随切换效果
Android 使用ViewPager实现手动左右切换页面和底部点点跟随切换效果
136 0
|
Android开发
flutter中实现仿Android端的onResume和onPause方法
flutter中实现仿Android端的onResume和onPause方法
|
8月前
|
Android开发
Android 使用ViewPager和自定义PagerAdapter实现轮播图效果
Android 使用ViewPager和自定义PagerAdapter实现轮播图效果
70 0
|
4月前
|
XML Java Android开发
Android Studio App开发之实现简单的启动引导页ViewPager(附源码 实现App的欢迎页面)
Android Studio App开发之实现简单的启动引导页ViewPager(附源码 实现App的欢迎页面)
83 1
|
6月前
|
Java Android开发
[笔记]Android 学习一之转场动画+ViewPager+ListView简单Demo
[笔记]Android 学习一之转场动画+ViewPager+ListView简单Demo
|
7月前
|
数据处理 Android开发
关于安卓viewpager实现堆叠卡片交互
关于安卓viewpager实现堆叠卡片交互
181 1
|
8月前
|
Android开发
Android 中ViewPager嵌套RecyclerView出现滑动冲突的解决方案
Android 中ViewPager嵌套RecyclerView出现滑动冲突的解决方案
703 0
|
8月前
|
XML Android开发 数据格式
Android 使用ViewPager实现基本的翻页效果
Android 使用ViewPager实现基本的翻页效果
94 0
|
11月前
|
XML Android开发 数据格式
Android 底部导航栏(四、ViewPager+RadioGroup+Fragment)简单易懂
底部导航栏在Android应用中随处可见,今天使用ViewPager+RadioGroup+Fragment这三个控件来实现此功能。前面写了有三种实现方式,有兴趣可以去看看