Android知乎广告效果
点击上方“程序员大咖”,选择“置顶公众号”
关键时刻,第一时间送达!
知乎的广告效果一直想写,无奈最近才有时间。
先看效果:
肯定要自定义view了,一个类似imageView的控件,还要给它一个值用来指定广告图片的显示位置。
问题:
1.图片如何在范围内(单个item范围)上下移动,如窗户一般,后面的图是可以动的,但是窗户是固定的。
2.图片移动的时机肯定和recycleView
滚动监听item有关,用哪些方法?
解决:
1.窗户问题首先想到imageView
的scaleType
属性,而scaleType
中只有matrix
和center
可以在不缩放图片的情况下显示一张大图中的部分,center
始终显示在图片中间部分,不符合要求,matrix
不指定显示位置。
2.recycleView
Item的滚动监听,刚好前段时间在仿写微博视频自动播放时接触过,recycleView
提供了一些譬如FindFirstVisibleItemPosition
(当前屏幕第一个item的position
),FindFirstCompletelyVisibleItemPosition
(当前屏幕第一个完全显示item的position
)等方法,可以利用这些方法,把当前的item找到,再利用instanceof
关键字比较当前item是不是我的广告item,如果是再想办法让广告图片动起来。
步骤:
1.自定义一个广告imageView,把他变成窗户:
继承imageView
,只需要重写他的2个方法,onSizeChanged
和onDraw
。
onSizeChanged
用来得到控件高度
onDraw
移动广告图片
int itemHeight = 0; //自定义imageView高度private float rate = 1; //初始化显示比率
@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); itemHeight = h; //广告item的高度}
@Overrideprotected void onDraw(Canvas canvas) { Drawable drawable = getDrawable(); if (drawable == null) { return; } int w = getWidth(); int h = (int) (getWidth() * 1.0f / drawable.getIntrinsicWidth() * drawable.getIntrinsicHeight()); drawable.setBounds(0, 0, w, h);//设置图片显示的绝对范围 int maxDy = h - itemHeight; //图片可以移动的最大距离为(图片有效移动距离): (0 ~ -maxDy) canvas.save(); canvas.translate(0, -rate * maxDy); super.onDraw(canvas); canvas.restore();}
public void setDy(int itemDy, int rvheight) { int allHeight = rvheight - itemHeight; //有效滑动高度(广告有效移动距离) rate = itemDy * 1f / allHeight;
if (rate <= 0) { rate = 0; } if (rate >= 1) { rate = 1; } invalidate();}
setDy方法可以先不管。
onDraw中说几个点:
super.onDraw(canvas)代码中的位置
super.onDraw(canvas)是实现原本imageView逻辑的地方,涉及自定义view绘制先后问题;假如我用canvas画了一个圆,画圆代码写在super之前:这个圆会先绘制出来,再走super,就会出现imageView把圆挡住的情况,画圆代码写在super之后:先走super再画圆,圆就在imageView的上面。参考上面代码中的super位置,先把图片的位置通过 canvas.translate方法移动之后,再利用super原本逻辑绘制出图片,就实现图片在窗口中移动的效果了。drawable.setBounds(l,t,r,b)方法
这个方法给图片设定一个绝对位置范围(或者说相对屏幕的显示范围),上面代码中的范围计算(参数r,b)其实就是 整个屏幕除开状态栏导航栏以外的范围(recycleView的范围)。 int w = getWidth()算出图片可以显示的最大宽度,再通过最大宽度 / 图片原本宽度 = 最大高度 / 图片原本高度 计算出最大高度 h。也就是int h = ….这一句。
通过onDraw方法,已经可以实现:一个imageView控件,动态的去移动它的内部图片。这个自定义的imageView就算是完成了。
2.获取recycleView监听以及位置计算
写监听之前想想如何把recycleView的item与自定义imageView联系起来,通过 canvas.translate(dx,dy)让图片动起来,必须要求出dy:
可以看看效果,只要广告的item有一点不在屏幕内,那么其中的图片是不会移动的,那么我们广告item有效移动距离就是整个recycleView的高度减去广告item的高度,如图绿色线:
而我们自定义imageView中图片有效移动距离是整个图片的高度减去窗口的高度,如图绿色线:(红色框就相当于自定义imageView窗口,整张图就是窗后可以translate的图片)
关系就出来了:
广告item位置 / 广告有效移动距离 = dy / 图片有效移动距离
重写RecyclerView.OnScrollListener中的onScrolled方法,我们要得到:广告item位置 和 广告有效移动距离
@Overridepublic void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy);
int first = layoutManager.findFirstCompletelyVisibleItemPosition(); //第一个完全显示的item int last = layoutManager.findLastCompletelyVisibleItemPosition(); //最后一个完全显示的item int firstPosition = layoutManager.findFirstVisibleItemPosition(); //第一个显示的item int lastPosition = layoutManager.findLastVisibleItemPosition(); //最后一个显示的item
//循环遍历当前屏幕中显示的所有item for (int i = firstPosition; i <= lastPosition; i++) { RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(i); //找出屏幕中的广告item if (viewHolder instanceof TxRecycleAdapter.ZhiHuHolder) { TxRecycleAdapter.ZhiHuHolder zhiHuHolder = (TxRecycleAdapter.ZhiHuHolder) viewHolder; View itemView = zhiHuHolder.itemView; //获取到广告item的位置 (item的顶部 与 recycleView顶部的距离) int top = itemView.getTop(); //获取recycleView的高度 int height = recyclerView.getHeight(); //调用自定义imageView中的方法,实现图片的移动 zhiHuHolder.adImageView.setDy(top, height); } }}
int top = itemView.getTop(); 广告item位置 = top, 广告有效移动距离 = recycleView的高度 - 广告item的高度,这一点的实现放在了自定义imageView的setDy方法中。
注意方法中的for循环
for (int i = firstPosition; i <= lastPosition; i++) {}
使用的是firstPosition和lastPosition,也就是//第一个显示的item和//最后一个显示的item。
知乎广告的效果是 广告item 完全显示才会去translate图片,一开始我使用的是first和last,他们正好也是完全显示的意思,for循环少走一两次挺好的;但是在验证效果的时候发现一个尴尬的问题:recycleView滑动速度过快,会出现广告item不能translate至底部或者顶部的情况;日志监视了一下,原因就是滑动过快。在代码中的表现是什么呢?自定义imageView中setDy()方法的rate变化异常。
rate等于1图片刚好显示在 顶部
rate等于0图片刚好显示在 底部
rate从0~1:
滑动慢 rate可能是这么变化的:0.05, 0.10,0.15,0.20 ……,0.80,0.85,0.90,0.95,1.0。
滑动快 rate可能是这么变化的:0.3,0.6,0.9。
压根就不会等于1或者等于0,那图片的translate位置肯定就不对了。
if (rate <= 0) {rate = 0;}if (rate >= 1) {rate = 1;}
刚已经通过recycleView的监听得到了广告item位置 与 广告有效移动距离,而 图片有效移动距离呢,它在自定义imageView中的onDraw方法得到:
int maxDy = h - itemHeight; //图片可以移动的最大距离为(图片有效移动距离): (0 ~ -maxDy)
最后,调用canvas.translate(0, -rate * maxDy);方法就可以实现整个效果了。
作者:达峰a
https://www.jianshu.com/p/5b3d8ff8ab64
程序员大咖整理发布,转载请联系作者获得授权
【点击成为源码大神】
Android知乎广告效果相关推荐
- 知乎广告效果怎么样?有哪些优势呢?
随着移动互联网的不断发展,在当下流量越来越贵的背景下,知乎平台以其独特的优势,特别失在内容营销方面独树一帜,相比较其它平台有着明显的优势,主要体现在 1.转化率高 因为知乎作为国内领先的互动问答平台, ...
- 纯CSS 实现知乎滑动广告效果
放个好看的头图先 最近的时候刷知乎看到了这种广告效果 emmmmm- 简书把图片转成了黑白,忽视这个细节吧. 效果分析 广告图片在信息流下面一层 在信息流的列表中留一个缝隙,就能看到下面一层的图片了 ...
- Android TextView竖直滚动文字广告效果
项目需要 TextView 单行竖直滚动文字广告效果,很简单的功能在网上找了很多没有想要的效果.开始找到的<android TextView 垂直自动滚动>,歌词效果,对代码处理一下变成单 ...
- android TextView向上滚动(模仿滚动文字广告效果)
android文字向上滚动效果没有自带的控件,这就需要开发者根据算法精确按照时间和坐标来实现TextView控件的向上移动,从网上找过几个框架,基本都会有bug,于是自己写了一个自定义控件,来实现Te ...
- android qq广告效果,手机怎么利用腾讯广告做品牌营销?
原标题:手机怎么利用腾讯广告做品牌营销? 1."换机"成市场主导,手机品牌何去何从 止戈蓝海割据战,开启阵营争夺战 当手机逐渐成为人们生活的必需品,国内手机市场亦日趋饱和.2018 ...
- Android之——史上最简单图片轮播广告效果实现
转载请注明出处:http://blog.csdn.net/l1028386804/article/details/48049913 如今的Android开发需求越来越来多,实现效果越来越酷炫,很多An ...
- 如何才能不看知乎广告?手机浏览器安装Edge扩展程序教程
title: 如何才能不看知乎广告?手机浏览器安装Edge扩展程序教程 tags: 知乎 简书 掘金 categories: 极客 知乎App的广告真的是越来越多了,问题与问题之间插广告,每个回答必插 ...
- 移动广告效果监测,App推广广告投放归因工具
Xinstall移动广告实时监控投放效果,精准监测各渠道曝光量.点击量.下载量.转化率等全链路核心数据,提供多平台数据聚合查看功能.报表加密分享功能.防作弊保护功能.帮助移动广告主量化移动端推广活动效 ...
- Android图片轮播效果
适配器 import android.support.v4.view.PagerAdapter; import android.util.Log; import android.view.View; ...
最新文章
- python检索字符串_python查找字符串所有子串
- 3D场景高级合成技术学习
- mac txt 换行符_推荐两款免费的网页代码编辑器(Win和Mac系统)
- 【每日一题】 面试题 17.14. 最小K个数
- 更改UISwitch大小
- 文件分布式存储实现例程
- Linux下的各文件夹的作用(转)
- 通俗地讲清楚fit_transform()和transform()的区别
- airflow mysql_Airflow 使用及原理分析
- 使用docker 起容器配置负载均衡(加权)
- java导致native非法指令,Java代码引起的NATIVE野指针问题(上)
- continue 与break 的区别
- linux命令大全(持续更新)
- IOS学习之斯坦福大学IOS开发课程笔记(第六课)
- Struts2之命名空间与Action的三种创建方式
- Autodesk 3DSMax 2012 安装说明
- 基于STM32cubemx的STM32F107vct6的代码生成,实验四串口与DMA
- Debian 10 开启和停止 ufw防火墙
- 浏览器html中加入word,web网页中加载word
- 微信支付——委托代扣介绍