关于安卓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 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 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 viewList = new ArrayList<>();

        public CusPagerAdapter(Context context, List 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----------------------------------------------------------------------------------

你可能感兴趣的:(安卓实战,android)