最近项目中有图片视频轮播的需求,网上扒拉一下发现效果不怎么好,总有这样那样的不满意,只好挖挖脑子自己写了。

        实现思路 viewpager中分类显示imageview和videoview。

直接上代码五个类快速实现

1、实体类

public class Advance {

    public String path;//路径  我使用的是本地绝对路径
    public String type;//类型 1、视频 2、图片

    public Advance(String path, String type) {
        this.path = path;
        this.type = type;
    }
}

2、用于展示图片的view。。使用glide加载图片

public class AdvanceImageView extends RelativeLayout {
    private ImageView imageView;

    public AdvanceImageView(Context context) {
        super(context);
        initView();
    }

    public AdvanceImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public AdvanceImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }


    private void initView() {
        imageView = new ImageView(getContext());
        imageView.setScaleType(ImageView.ScaleType.FIT_XY);
        addView(imageView, new RelativeLayout.LayoutParams(-1, -1));
    }

    public void setImage(String path) {
        Glide.with(getContext()).load(path).into(imageView);
    }

}

3、用于展示视频的view

public class AdvanceVideoView extends RelativeLayout {
    private ImageView imageView;
    private VideoView videoView;
    private RelativeLayout videoRela;
    private String path;

    public AdvanceVideoView(Context context) {
        super(context);
        initView();
    }

    public AdvanceVideoView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public AdvanceVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    private void initView() {
        videoRela = new RelativeLayout(getContext());
        addView(videoRela, new RelativeLayout.LayoutParams(-1, -1));
        imageView = new ImageView(getContext());
        imageView.setScaleType(ImageView.ScaleType.FIT_XY);
        addView(imageView, new RelativeLayout.LayoutParams(-1, -1));
    }

    public void setImage(String path) {
        this.path = path;
        Glide.with(getContext()).load(path).into(imageView);
    }

    public void setVideo(MediaPlayer.OnCompletionListener onCompletionListener) {
        if (videoView != null) {
            videoRela.removeView(videoView);
            videoView = null;
        }
        videoView = new VideoView(getContext());
        videoView.setVideoPath(path);
        videoView.setBackgroundColor(Color.TRANSPARENT);
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(-1, -1);
        //设置videoview占满父view播放
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
        videoRela.addView(videoView, layoutParams);
        videoView.setOnCompletionListener(onCompletionListener);
        videoView.start();
        videoView.setOnPreparedListener(mediaPlayer -> {
            new Handler().postDelayed(() -> {
                imageView.setVisibility(GONE);
            }, 400);//防止videoview播放视频前有个闪烁的黑屏
        });
    }

    public void setPause() {
        if (videoView != null) {
            videoView.pause();
            imageView.setVisibility(VISIBLE);
        }
    }

    public void setRestart() {
        if (videoView != null) {
            videoView.start();
            imageView.setVisibility(GONE);
        }
    }
}

4、用于对接数据的view


public class AdvanceView extends RelativeLayout {
    private ViewPager viewPager;
    private List<View> views = new ArrayList<>();
    private AdvancePagerAdapter adapter;

    public AdvanceView(Context context) {
        super(context);
        initView();
    }

    public AdvanceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public AdvanceView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    private void initView() {
        viewPager = new ViewPager(getContext());
        adapter = new AdvancePagerAdapter(getContext(),viewPager);
        viewPager.setAdapter(adapter);
        addView(viewPager, new RelativeLayout.LayoutParams(-1, -1));
    }

    public void setData(List<Advance> advances) {
        adapter.setData(advances);

    }

    public void setPause(){
        adapter.setPause();
    }
    public void setResume(){
        adapter.setResume();
    }
}

5、重头戏 我的操作都在这了 pageradapter

public class AdvancePagerAdapter extends PagerAdapter implements ViewPager.OnPageChangeListener {
    private Context context;
    private ViewPager viewPager;
    private List<Advance> datas;
    private List<View> list = new ArrayList<>();

    private int current = 0;
    private int time = 5000;
    private boolean pause;
    private Thread thread;

    private int lastPosition = -1;

    public AdvancePagerAdapter(Context context, ViewPager viewPager) {
        this.context = context;
        this.viewPager = viewPager;
    }


    public void setData(List<Advance> advances) {
        if (advances.size() == 0) return;
        this.datas = advances;
        list.clear();
        if (advances != null) {
            addView(advances.get(advances.size() - 1));
            if (advances.size() > 1) { //多于1个要循环
                for (Advance d : advances) { //中间的N个(index:1~N)
                    addView(d);
                }
                addView(advances.get(0));
            }
        }
        viewPager.addOnPageChangeListener(this);
        notifyDataSetChanged();
        //在外层,将mViewPager初始位置设置为1即可
        if (advances.size() > 1) { //多于1个,才循环并开启定时器
            viewPager.setCurrentItem(1);
            startTimer();
        }
        if (advances.get(0).type.equals("1")) {//有人反应第一个是视频不播放这边优化了一下
            ((AdvanceVideoView) list.get(viewPager.getCurrentItem())).setVideo(mediaPlayer -> {
                viewPager.setCurrentItem(viewPager.getCurrentItem() + 1, true);
            });
        }
    }

    private void addView(Advance advance) {
        if (advance.type.equals("1")) {
            AdvanceVideoView videoView = new AdvanceVideoView(context);
            videoView.setImage(advance.path);
            list.add(videoView);
        } else {
            AdvanceImageView imageView = new AdvanceImageView(context);
            imageView.setImage(advance.path);
            list.add(imageView);
        }
    }

    private void startTimer() {
        if (thread != null && !thread.isInterrupted()) {
            thread.interrupt();
            thread = null;
        }
        thread = new Thread(() -> {
            while (thread != null && !thread.isInterrupted()) {
                try {
                    Thread.sleep(1000);
                    if (!pause && !(list.get(viewPager.getCurrentItem()) instanceof AdvanceVideoView))
                        current += 1000;
                    if (current >= time) {
                        viewPager.post(() -> viewPager.setCurrentItem(viewPager.getCurrentItem() + 1, true));
                        current = 0;
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
    }

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

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

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView(list.get(position));
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        View view = list.get(position);
        container.addView(view);
        return view;
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

    //
//    // 实现ViewPager.OnPageChangeListener接口
    @Override
    public void onPageSelected(int position) {

    }

    @Override
    public void onPageScrolled(int position, float positionOffset,
                               int positionOffsetPixels) {
        // 什么都不干
    }

    @Override
    public void onPageScrollStateChanged(int state) {
        // 由于viewpager的预加载机制onPageSelected这里面加载videoview 放的跟玩一样  等操作完成后再播放videoview就香了  很丝滑
        Log.d("", "");
        if (state == 0) {
            if (list.size() > 1) { //多于1,才会循环跳转
                if (lastPosition != -1 && lastPosition != viewPager.getCurrentItem() && list.get(lastPosition) instanceof AdvanceVideoView) {
                    ((AdvanceVideoView) list.get(lastPosition)).setPause();
                }
                if (viewPager.getCurrentItem() < 1) { //首位之前,跳转到末尾(N)
                    int position = datas.size(); //注意这里是mList,而不是mViews
                    viewPager.setCurrentItem(position, false);
                } else if (viewPager.getCurrentItem() > datas.size()) { //末位之后,跳转到首位(1)
                    viewPager.setCurrentItem(1, false); //false:不显示跳转过程的动画
                }
                current = 0;//换页重新计算时间
                if (list.get(viewPager.getCurrentItem()) instanceof AdvanceVideoView) {
                    ((AdvanceVideoView) list.get(viewPager.getCurrentItem())).setVideo(mediaPlayer -> {
                        viewPager.setCurrentItem(viewPager.getCurrentItem() + 1, true);
                    });
                }
                lastPosition = viewPager.getCurrentItem();
            }
        }
    }

    public void setPause() {
        pause = true;
        if (list.size() > 0 && list.get(viewPager.getCurrentItem()) instanceof AdvanceVideoView) {
            ((AdvanceVideoView) list.get(viewPager.getCurrentItem())).setPause();
            Log.e("调用暂停", " pause");
        }
    }

    public void setResume() {
        pause = false;
        if (list.size() > 0 && list.get(viewPager.getCurrentItem()) instanceof AdvanceVideoView) {
            ((AdvanceVideoView) list.get(viewPager.getCurrentItem())).setRestart();
            Log.e("调用start", " start");
        }
    }
}

源码已经完成,需要的话自己看吧。

调用简单了

activity  xml中


            <AdvanceView
                android:id="@+id/banner"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>

activity中

AdvanceView advanceView = findViewById(R.id.banner);
List<Advance> data = new ArrayList<>();
//数据加加
advanceView.setData(data);


@Override
protected void onResume() {
   super.onResume();
   advanceView.setResume();
}

@Override
protected void onPause() {
   super.onPause();
   advanceView.setPause();
}

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐