本文将持续更新,打造一个完整的智能广告发布系统。
一.效果
本篇最终实现播放效果:
广告机上部播放图片,下部播放视频。
二.用到的工具
(1)使用 convenientbanner作为图片轮播的工具
(2)使用 glide 作为图片缓存的工具
(3)使用 videocache 作为视频缓存的工具
(4)视频播放采用安卓自带的 videoview.
以下为相关工具依赖:
//图片缓存框架 compile 'com.github.bumptech.glide:glide:3.7.0' //图片轮播框架 compile 'com.bigkoo:convenientbanner:2.0.5' //视频缓存控件 compile 'com.danikula:videocache:2.7.0'
三.实现逻辑及代码
3.1逻辑简述
主activity包含fragment。在activity中绑定并加载fragment,在fragment中进行加载图片--》播放图片;加载视频--》播放视频。
3.2 activity布局代码
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v4.view.ViewPager android:id="@+id/mViewPager" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> </LinearLayout>
3.3 fragment布局代码
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:background="#000000" android:layout_width="match_parent" android:layout_height="match_parent"> <com.bigkoo.convenientbanner.ConvenientBanner xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/convenientBanner" android:layout_width="match_parent" android:layout_height="500dp" app:canLoop="true"/> <VideoView android:id="@+id/mVideoView" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
3.4 activity逻辑代码
使用viewpager进行fragment绑定,并且viewpager可以加载多个fragment从而使用多场景(不同布局节目)广告播放。
private List<Fragment> mFragment; private ViewPager mViewPager; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_ad_play); initData(); initView(); } private void initView() { mViewPager = (ViewPager) findViewById(R.id.mViewPager); mViewPager.setOffscreenPageLimit(mFragment.size()); //设置适配器 mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) { //选中的item @Override public Fragment getItem(int position) { return mFragment.get(position); } //返回item的个数 @Override public int getCount() { return mFragment.size(); } }); } private void initData() { mFragment = new ArrayList<>(); mFragment.add(new AdvertFragment()); }
3.5 fragment逻辑代码
convenientBanner在进行图片加载时,默认第一次加载时根据url就行网络加载,此后每次会从本地取(会自动判断url是否已经加载过)。
private ConvenientBanner convenientBanner; private String[] images; private List<String> networkImage; private VideoView videoView; //视频缓存代理 private HttpProxyCacheServer proxy; private View advert; //protected ImageLoader @Override public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) { advert = inflater.inflate(R.layout.advert_fragment,container,false) ; initImages(); initVideo(); return advert; } private void initVideo() { proxy = new HttpProxyCacheServer.Builder(getActivity()) .maxCacheSize(1024 * 1024 * 1024) .maxCacheFilesCount(20) .build(); videoView = advert.findViewById(R.id.mVideoView); videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() { @Override public boolean onError(MediaPlayer mp, int what, int extra) { videoView.stopPlayback(); //播放异常,则停止播放,防止弹窗使界面阻塞 return true; } }); playVideoOne();//播放第一个视频 } //加载并播放图片 private void initImages() { //将目标图片url装进数组 images = new String[]{"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1561790287581&di=07fef06182929d93688a94f9130b4d9a&imgtype=0&src=http%3A%2F%2Fpic37.nipic.com%2F20140113%2F8800276_184927469000_2.png","https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1561790287581&di=07fef06182929d93688a94f9130b4d9a&imgtype=0&src=http%3A%2F%2Fpic37.nipic.com%2F20140113%2F8800276_184927469000_2.png","https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1561811928059&di=5e95696c17100ddcd9a38914406c14db&imgtype=0&src=http%3A%2F%2Fpic31.nipic.com%2F20130801%2F11604791_100539834000_2.jpg","https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1561811952654&di=27c19b7c1780478f08ee24616fde7a43&imgtype=0&src=http%3A%2F%2Fimg.redocn.com%2Fsheji%2F20141219%2Fzhongguofengdaodeliyizhanbanzhijing_3744115.jpg"}; convenientBanner = advert.findViewById(R.id.convenientBanner); //网络加载图片 networkImage = Arrays.asList(images); convenientBanner.setPages(new CBViewHolderCreator<NetWorkImageViewHolderTest>() { @Override public NetWorkImageViewHolderTest createHolder() { return new NetWorkImageViewHolderTest(); } },networkImage) //切换时间 .startTurning(5000) //是否开启手动切换 .setManualPageable(false); } //加载并播放视频 public void playVideoOne(){ String proxyUrl = proxy.getProxyUrl("https://vd2.bdstatic.com/mda-jftw7y8w3c826gpt/hd/mda-jftw7y8w3c826gpt.mp4?auth_key=1561806031-0-0-cf277fe52ac69ebf634ffd248c40c683&bcevod_channel=searchbox_feed&pd=unknown&abtest=all"); //视频url拼接日期,实现按日更新 videoView.setVideoPath(proxyUrl); //为videoview设置播放路径,而不是设置播放url videoView.start(); videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mPlayer) { //playVideoTwo(); //监听视频一的播放完成事件,播放完毕就播放视频二 } }); } // public void playVideoTwo(){ // String proxyUrl = proxy.getProxyUrl(videoTwoUrl); // videoView.setVideoPath(proxyUrl); // videoView.start(); // videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { // @Override // public void onCompletion(MediaPlayer mPlayer) { // playVideoThree(); // } // }); // } // public void playVideoThree(){ // String proxyUrl = proxy.getProxyUrl(videoThreeUrl); // videoView.setVideoPath(proxyUrl); // videoView.start(); // videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { // @Override // public void onCompletion(MediaPlayer mPlayer) { // playVideoOne();//视频三播放完后播放视频一,从而实现轮播 // } // }); // }