效果图



效果图依次为图片广告,视频广告,引导界面。

系列文章目录导航

目录

1.实现分析

广告界面就是显示图片和视频,所以可以放一个图片控件,视频控件,然后跳过按钮,提示按钮,WiFi预加载提示都是放到最上层容器。

2.广告界面布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".component.ad.activity.AdActivity">
<!--图片广告-->
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" /> <!--视频播放器
VideoView默认没法设置视频填充整个控件,所以不用他-->
<com.tencent.rtmp.ui.TXCloudVideoView
android:id="@+id/video"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
<!--/播放器--> <!--广告控制层-->
<RelativeLayout
android:id="@+id/ad_control"
android:layout_width="match_parent"
android:layout_height="match_parent"> <TextView
android:id="@+id/preload"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/padding_meddle"
android:layout_marginTop="@dimen/d50"
android:layout_marginBottom="@dimen/d50"
android:background="@drawable/shape_button_transparent_radius_small"
android:gravity="center"
android:padding="@dimen/d5"
android:text="@string/wifi_preload"
android:textColor="?attr/colorLightWhite"
android:textSize="@dimen/text_small"
android:visibility="gone" /> <!--跳过广告按钮-->
<TextView
android:id="@+id/skip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginTop="@dimen/d50"
android:layout_marginRight="@dimen/padding_large"
android:layout_marginBottom="@dimen/d50"
android:background="@drawable/shape_button_transparent_radius_small"
android:gravity="center"
android:padding="@dimen/padding_meddle"
android:textColor="?attr/colorLightWhite"
android:textSize="@dimen/text_meddle"
app:cornerRadius="@dimen/d30"
tools:text="@string/skip_ad_count" />
<!--打开广告按钮-->
<TextView
android:id="@+id/primary"
android:layout_width="match_parent"
android:layout_height="@dimen/d60"
android:background="@drawable/shape_button_transparent_radius_large"
android:gravity="center"
android:text="@string/ad_click_tip"
android:textColor="?attr/colorLightWhite"
android:textSize="@dimen/text_large"
app:cornerRadius="@dimen/d30" />
</com.facebook.shimmer.ShimmerFrameLayout>
</RelativeLayout>
</RelativeLayout>

3.显示广告

广告数据是在首页提前缓存到本地了,目的是本地显示更快,因为广告界面本来就几秒钟,还要去网络请求数据,就很浪费时间。

@Override
protected void initDatum() {
super.initDatum(); //获取广告信息
data = sp.getSplashAd();
if (data == null) {
next();
return;
} //显示广告信息
show();
} private void show() {
File targetFile = FileUtil.adFile(getHostActivity(), data.getIcon());
if (!targetFile.exists()) {
//记录日志,因为正常来说,只要保存了,文件不能丢失
next();
return;
} SuperViewUtil.show(binding.adControl); switch (data.getStyle()) {
case Constant.VALUE0:
showImageAd(targetFile);
break;
case Constant.VALUE10:
showVideoAd(targetFile);
break;
}
} /**
* 显示视频广告
*
* @param data
*/
private void showVideoAd(File data) {
SuperViewUtil.show(binding.video);
SuperViewUtil.show(binding.preload); //在要用到的时候在初始化,更节省资源,当然播放器控件也可以在这里动态创建
//设置播放监听器 //创建 player 对象
player = new TXVodPlayer(getHostActivity()); //静音,当然也可以在界面上添加静音切换按钮
player.setMute(true); //关键 player 对象与界面 view
player.setPlayerView(binding.video); //设置播放监听器
player.setVodListener(this); //铺满
binding.video.setRenderMode(TXLiveConstants.RENDER_MODE_FULL_FILL_SCREEN); //开启硬件加速
player.enableHardwareDecode(true); player.startPlay(data.getAbsolutePath());
} /**
* 显示图片广告
*
* @param data
*/
private void showImageAd(File data) {
ImageUtil.showLocalImage(getHostActivity(), binding.image, data.getAbsolutePath()); startCountDown(5000);
}

跳过广告

跳过广告就是取消倒计时,直接进入下一个界面。

//跳过广告按钮
binding.skip.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//取消倒计时
cancelCountDown(); next();
}
});

点击广告

点击广告就是取消倒计时,进入主界面,然后再显示广告界面。


引导界面布局

//点击广告按钮
binding.primary.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//取消倒计时
cancelCountDown(); action = Constant.ACTION_AD; next();
}
});

引导界面逻辑

顶部左右滚动ViewPager容器,也可以使用ViewPager2,中间就是指示器,底部就是按钮。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ixuea="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"> <!--左右滚动控件-->
<androidx.viewpager.widget.ViewPager
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" /> ... <!--按钮容器-->
<LinearLayout
android:layout_marginBottom="@dimen/d30"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"> <!--占位控件-->
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" /> <!--登录注册按钮-->
<com.google.android.material.button.MaterialButton
android:id="@+id/login_or_register"
style="@style/SuperButton.Primary"
android:layout_width="wrap_content"
android:minWidth="@dimen/d130"
android:text="@string/login_or_register" /> <include layout="@layout/fill" /> <!--立即体验按钮-->
<com.google.android.material.button.MaterialButton
android:id="@+id/experience_now"
style="@style/Widget.MaterialComponents.Button.UnelevatedButton"
android:layout_width="wrap_content"
android:layout_height="@dimen/d55"
android:layout_centerVertical="true"
android:layout_marginHorizontal="@dimen/d5"
android:layout_toRightOf="@+id/select_image"
android:backgroundTint="?attr/colorLightWhite"
android:minWidth="@dimen/button_width_large"
android:text="@string/experience_now"
android:textColor="@color/black80"
android:textSize="@dimen/text_small"
ixuea:strokeColor="?attr/colorPrimary"
ixuea:strokeWidth="@dimen/d1" /> <include layout="@layout/fill" />
</LinearLayout>
</LinearLayout>

下载广告

不论是图片,还是视频都按照文件方式下,当然下载前还要判断是WiFi,以及没有下载才下载。

private void downloadAd(Ad data) {
if (SuperNetworkUtil.isWifiConnected(getHostActivity())) {
sp.setSplashAd(data); //判断文件是否存在,如果存在就不下载
File targetFile = FileUtil.adFile(getHostActivity(), data.getIcon());
if (targetFile.exists()) {
return;
} new Thread(
new Runnable() {
@Override
public void run() { try {
//FutureTarget会阻塞
//所以需要在子线程调用
FutureTarget<File> target = Glide.with(getHostActivity().getApplicationContext())
.asFile()
.load(ResourceUtil.resourceUri(data.getIcon()))
.submit(); //获取下载的文件
File file = target.get(); //将文件拷贝到我们需要的位置
FileUtils.moveFile(file, targetFile); } catch (Exception e) {
e.printStackTrace();
}
}
}
).start();
}
}

总结

不论是那个界面,都没有很难,但就像我们说的,写代码就像艺术,要写好细节还挺麻烦,例如:下载广告是否应该登录网络空闲时才下载,避免影响正常网络请求,同时下载下来后,要添加一定的机制,防止很容易的跳过广告等;如果要产生收益,大公司就是有自己的广告平台,中小型项目可以使用聚合SDK更方便。

最新文章

  1. Beginning Scala study note(6) Scala Collections
  2. 将数据导出成excel表
  3. Portable Operating System Interface for uni-X
  4. Mono addin 学习笔记 2
  5. win32手动创建windows窗口的,小记
  6. C# 代码转化为Java代码
  7. eclipse不能打断点的问题
  8. jquery easyui combobox
  9. prototype原型理解
  10. and or判别
  11. VPS选购及辨别vps虚拟化技术
  12. 遮罩层的实现(纯js兼容版)
  13. spring 入门篇
  14. Cocos2d-x3.0 RenderTexture(一) 保存
  15. WCF从零学习之设计和实现服务协定2
  16. HDU 3265 Posters ——(线段树+扫描线)
  17. 分30条依次解析xml并插入数据库成功
  18. 管道模式——pipeline与valve
  19. React-Native采坑总结
  20. leaflet 如何绘制圆

热门文章

  1. 小数据池,is和==的区别,id()
  2. ansible模块的介绍与使用
  3. Android 12(S) 图像显示系统 - SurfaceFlinger GPU合成/CLIENT合成方式 - 随笔1
  4. Celery-Task参数方法
  5. 485. Max Consecutive Ones - LeetCode
  6. MySQL之SQL语句优化
  7. mac安装java环境
  8. 【JNPF修改通告】fastjson≤1.2.80反序列化漏洞
  9. npm错误:Cannot find module ‘compression-webpack-plugin
  10. 【Java并发编程】Synchronized关键字实现原理