最近项目中有图片视频轮播的需求,网上扒拉一下发现效果不怎么好,总有这样那样的不满意,只好挖挖脑子自己写了。
实现思路 viewpager中分类显示imageview和videoview。
直接上代码五个类快速实现
1、实体类
public class Advance {public String path;//路径 我使用的是本地绝对路径public String type;//类型 1、视频 2、图片public Advance(String path, String type) {this.path = pe = 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) {veView(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) {t = context;this.viewPager = viewPager;}public void setData(List<Advance> advances) {if (advances.size() == 0) return;this.datas = advances;list.clear();if (advances != null) {(advances.size() - 1));if (advances.size() > 1) { //多于1个要循环for (Advance d : advances) { //中间的N个(index:1~N)addView(d);}(0));}}viewPager.addOnPageChangeListener(this);notifyDataSetChanged();//在外层,将mViewPager初始位置设置为1即可if (advances.size() > 1) { //多于1个,才循环并开启定时器viewPager.setCurrentItem(1);startTimer();}if ((0).type.equals("1")) {//有人反应第一个是视频不播放这边优化了一下((AdvanceVideoView) (CurrentItem())).setVideo(mediaPlayer -> {viewPager.CurrentItem() + 1, true);});}}private void addView(Advance advance) {if (pe.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 && !((CurrentItem()) instanceof AdvanceVideoView))current += 1000;if (current >= time) {viewPager.post(() -> viewPager.CurrentItem() + 1, true));current = 0;}} catch (InterruptedException e) {e.printStackTrace();}}});thread.start();}@Overridepublic int getCount() {return list.size();}@Overridepublic boolean isViewFromObject(View view, Object object) {return view == object;}@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {(position));}@Overridepublic Object instantiateItem(ViewGroup container, int position) {View view = (position);container.addView(view);return view;}@Overridepublic int getItemPosition(Object object) {return POSITION_NONE;}//
// // 实现ViewPager.OnPageChangeListener接口@Overridepublic void onPageSelected(int position) {}@Overridepublic void onPageScrolled(int position, float positionOffset,int positionOffsetPixels) {// 什么都不干}@Overridepublic void onPageScrollStateChanged(int state) {// 由于viewpager的预加载机制onPageSelected这里面加载videoview 放的跟玩一样 等操作完成后再播放videoview就香了 很丝滑Log.d("", "");if (state == 0) {if (list.size() > 1) { //多于1,才会循环跳转if (lastPosition != -1 && lastPosition != CurrentItem() && (lastPosition) instanceof AdvanceVideoView) {((AdvanceVideoView) (lastPosition)).setPause();}if (CurrentItem() < 1) { //首位之前,跳转到末尾(N)int position = datas.size(); //注意这里是mList,而不是mViewsviewPager.setCurrentItem(position, false);} else if (CurrentItem() > datas.size()) { //末位之后,跳转到首位(1)viewPager.setCurrentItem(1, false); //false:不显示跳转过程的动画}current = 0;//换页重新计算时间if ((CurrentItem()) instanceof AdvanceVideoView) {((AdvanceVideoView) (CurrentItem())).setVideo(mediaPlayer -> {viewPager.CurrentItem() + 1, true);});}lastPosition = CurrentItem();}}}public void setPause() {pause = true;if (list.size() > 0 && (CurrentItem()) instanceof AdvanceVideoView) {((AdvanceVideoView) (CurrentItem())).setPause();Log.e("调用暂停", " pause");}}public void setResume() {pause = false;if (list.size() > 0 && (CurrentItem()) instanceof AdvanceVideoView) {((AdvanceVideoView) (CurrentItem())).setRestart();Log.e("调用start", " start");}}
}
源码已经完成,需要的话自己看吧。
调用简单了
activity xml中
<AdvanceViewandroid: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() {Resume();advanceView.setResume();
}@Override
protected void onPause() {Pause();advanceView.setPause();
}
本文发布于:2024-01-28 12:20:02,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/17064156057376.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |