Android如何知乎广告效果(android,移动开发)

时间:2024-05-07 02:04:07 作者 : 石家庄SEO 分类 : 移动开发
  • TAG :

知乎的广告效果一直想写,无奈最近才有时间。

先看效果:

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移动广告图片

intitemHeight=0;//自定义imageView高度privatefloatrate=1;//初始化显示比率@OverrideprotectedvoidonSizeChanged(intw,inth,intoldw,intoldh){super.onSizeChanged(w,h,oldw,oldh);itemHeight=h;//广告item的高度}@OverrideprotectedvoidonDraw(Canvascanvas){Drawabledrawable=getDrawable();if(drawable==null){return;}intw=getWidth();inth=(int)(getWidth()*1.0f/drawable.getIntrinsicWidth()*drawable.getIntrinsicHeight());drawable.setBounds(0,0,w,h);//设置图片显示的绝对范围intmaxDy=h-itemHeight;//图片可以移动的最大距离为(图片有效移动距离):(0~-maxDy)canvas.save();canvas.translate(0,-rate*maxDy);super.onDraw(canvas);canvas.restore();}publicvoidsetDy(intitemDy,intrvheight){intallHeight=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原本逻辑绘制出图片,就实现图片在窗口中移动的效果了。 (此番解释只针对继承已有的imageview,textview等,如果是继承View,super位置就很随意了,因为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的高度,如图绿色线:

Android如何知乎广告效果

而我们自定义imageView中图片有效移动距离是整个图片的高度减去窗口的高度,如图绿色线:(红色框就相当于自定义imageView窗口,整张图就是窗后可以translate的图片)

Android如何知乎广告效果

关系就出来了: 广告item位置 / 广告有效移动距离 = dy / 图片有效移动距离

重写RecyclerView.OnScrollListener中的onScrolled方法,我们要得到:广告item位置 和 广告有效移动距离

@OverridepublicvoidonScrolled(RecyclerViewrecyclerView,intdx,intdy){super.onScrolled(recyclerView,dx,dy);intfirst=layoutManager.findFirstCompletelyVisibleItemPosition();//第一个完全显示的itemintlast=layoutManager.findLastCompletelyVisibleItemPosition();//最后一个完全显示的itemintfirstPosition=layoutManager.findFirstVisibleItemPosition();//第一个显示的itemintlastPosition=layoutManager.findLastVisibleItemPosition();//最后一个显示的item//循环遍历当前屏幕中显示的所有itemfor(inti=firstPosition;i<=lastPosition;i++){RecyclerView.ViewHolderviewHolder=recyclerView.findViewHolderForAdapterPosition(i);//找出屏幕中的广告itemif(viewHolderinstanceofTxRecycleAdapter.ZhiHuHolder){TxRecycleAdapter.ZhiHuHolderzhiHuHolder=(TxRecycleAdapter.ZhiHuHolder)viewHolder;ViewitemView=zhiHuHolder.itemView;//获取到广告item的位置(item的顶部与recycleView顶部的距离)inttop=itemView.getTop();//获取recycleView的高度intheight=recyclerView.getHeight();//调用自定义imageView中的方法,实现图片的移动zhiHuHolder.adImageView.setDy(top,height);}}}

int top = itemView.getTop(); top = 广告item位置;
广告有效移动距离 = recycleView的高度 - 广告item的高度,这一点的实现放在了自定义imageView的setDy方法中。
注意方法中的for循环

for (int i = firstPosition; i <= lastPosition; i++) {}

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位置肯定就不对了。

出现这个问题我试过很多方法,比如速度跟踪类(VelocityTracker)计算速度,当速度大了再根据滑动方向直接置顶或者置底,获取广告item可见性置顶或者置底.....等等。有些方法可能有点用,但是太麻烦了,最后直接在for循环中用firstPosition和lastPosition,这样,虽然会出现rate = - 0.2 这样的负值,但是你只要给个判断就可以了:

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);方法就可以实现整个效果了。

 </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:Android如何知乎广告效果的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:如何实现仿ios状态栏颜色和标题栏颜色一致下一篇:

9 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18