-
甜品的创意广告词大全_餐饮创意幽默广告语
2020-12-03 16:27:10甜品的创意广告词大全 甜品,也叫甜点,是一个很广的概念,大致分为甜味点心和广式的糖水。那么它有哪些的广告词呢?下面小编为大家带来经典的内容,欢迎大家参考! 甜品的经典广告词 1. 怎么表达,都能称职 2. 有... -
创意广告设计模板PSD
2019-11-26 19:38:51创意广告设计模板PSD -
突破创意广告公司网页模板
2021-01-19 23:33:43突破创意广告公司网页模板 -
创意广告设计互动官网模板
2019-11-30 04:11:16创意广告设计互动官网模板是一款黑色精品创意广告设计互动官网网站模板下载。提示:本模板调用到谷歌字体库,可能会出现页面打开比较缓慢。 -
创意广告文案分析ppt模板
2020-08-24 20:10:42创意广告文案分析ppt模板适用于商务办公设计应用。由【素材】原创 -
蓝色创意广告公司html5模板
2019-11-30 16:05:20蓝色创意广告公司html5模板是一款适合广告创意策划公司单页网站模板下载。 -
品牌宣传创意广告词欣赏_纸包鱼开业广告宣传语
2020-12-03 16:26:46品牌宣传创意广告词欣赏 很多的品牌为了提升知名度,都会有创作很多创意的广告词来进行宣传。下面是小编整理的品牌宣传创意广告词,分享给大家!创意广告词 1. 放低偏见,你会有精彩发现!出自:柯尼卡 2. 喝汇源... -
广告策划书创意广告策划案_精选.doc
2020-12-04 12:39:12广告策划书创意广告策划案 相信你看过的广告也有很多了,那么如何自己写一份广告策划书呢,以下是小编精心收集整理的广告策划方案,下面小编就和大家分享,来欣赏一下吧。 广告策划书1 1、活动主题:浪漫平安夜,狂欢... -
百事可乐创意广告标语_精选.doc
2020-12-03 16:27:09百事可乐创意广告标语 百事可乐是一家百年老品牌公司,在其产品可乐的广告语总是别出心裁,迅速抓到市场的需求,这不仅得益于公司的制度文化,还得益于产品的广告宣传深入人心,下面整理百事可乐创意广告标语,欢迎... -
蓝白色系创意广告设计企业网站html模板
2021-02-24 15:14:58蓝白色系创意广告设计企业网站html模板 -
经典英文创意广告词大全_精选.doc
2020-12-03 16:27:32经典英文创意广告词大全 我们接触很多的广告,心里面或许早已知道广告的表达。但有些英文广告比较的有创意,其中不缺脑洞打开的广告表现,让我们感觉像是在看一场小电影,下面小编整理经典英文创意广告词大全,欢迎... -
卖面膜创意广告语_精选.doc
2020-12-03 16:27:08卖面膜创意广告语 年轻漂亮是每个女人的共同愿望,随着年龄的逐渐增长,肌肤不再年轻依旧,于是关于面膜的广告语应运而生,下面小编整理关于“卖面膜创意广告语”,希望大家喜欢。 卖面膜创意广告语 1、一夜还原... -
PPT模板-创意广告设计欣赏.dpt
2019-09-07 16:45:30PPT模板-创意广告设计欣赏.dpt -
美白产品的创意广告词大全_关于美白的搞笑广告词
2020-12-03 16:27:11美白产品的创意广告词大全 人人爱美,一白遮三丑,美白产品广告在人们的生活中越来越常见,那么你对那些广告词有熟悉感呢下面小编为你带来的经典内容,希望对你有所帮助! 最新美白产品的经典广告词 1. 防晒+隔离受... -
女士内裤创意广告语标语_精选.doc
2020-12-03 16:27:09女士内裤创意广告语标语 展示典雅时尚,品味迷人身材。如何将女士内裤通过高端优雅的方式推广出去呢,那么创意的广告语是十分有必要的,下面小编整理女士内裤创意广告语标语,欢迎大家阅读。 女士内裤创意广告语... -
汽车创意广告词大全_精选.doc
2020-12-03 16:27:20汽车创意广告词大全 汽车的品牌和数量都逐渐的增多,那么它们都有怎样的广告词呢?下面是小编带来关于汽车广告词大全的内容,希望能让大家有所收获! 汽车广告词 1. 克莱斯勒汽车广告语―――你买汽车不来考虑一下... -
房地产楼盘创意广告词大全_精选.doc
2020-12-03 16:27:12房地产楼盘创意广告词大全 现在有很多房地产的广告,为了吸引更多的客户,使用一些很有创意的广告词。下面是小编带来关于房地产楼盘创意广告词的内容,希望能让大家有所收获! 房地产楼盘创意广告词大全 1. 城市... -
Android 仿知乎创意广告 广告还能这么玩
2019-02-08 10:43:01Android 仿知乎创意广告 广告还能这么玩本文已在我的公众号hongyangAndroid原创首发。
转载请标明出处:
http://blog.csdn.net/lmj623565791/article/details/78714705
本文出自张鸿洋的博客一、概述
貌似前段时间刷知乎看到的一种非常有特色的广告展现方式,即在列表页,某一个Item显示背后部分广告图,随着列表滚动,会逐渐展示全部图片。
刚看到的时候就想实现一哈,一直比较懒,公众号后台也有人问如何实现,今天来给大家讲解下,当然了,目前一些自定义View已经不算难题,所以本文的讲解会做一些实现思路引导,相信不会是那么枯燥的文章,希望对大家有一定的帮助。
恩,现在知乎上已经找不到该效果了,试了多个历史版本也没找到,那只能贴实现的效果图了~
效果图如下:
2选1,你喜欢哪个效果图呢~~
二、思路
好了,抛开别的,确定下本文的目标:
实现在列表中展示某张图片:
往上滚动:在图片刚出现时展示顶部部分,随着滚动部分展示全部
往下滚动:在图片刚出现时展示底部部分,随着滚动部分展示全部换句话说,我们需要在列表滚动时,改变图片显示的部分。
两个点:
- 捕获列表滚动的dy,不管是ListView还是RecyclerView相信这一点都能做到
- 图片显示部分变化,我们可以利用canvas.translate
结合一下,就是,监听列表的滚动dy,传给我们的图片控件,设置translate,然后绘制。
到这里,思路非常清晰,这个东西肯定能做了。
初步方案:自定义一个View,自己去绘制bitmap,对外暴露setDy(dy),然后根据dy做canvas偏移重绘即可。
有了初步方案,基本不慌了,那么再想想?
能否利用已有的控件,比如ImageView呢?
肯定可以,这样省去了我们去声明一个接受图片的属性,我们编写一个子类,依然是通过设置src去使用。
那继承ImageView实现一波再说。
开始码代码前,力推下我的公众号:
专注于Android的相关技术~
三、实现
首先我们先写个假的列表,鉴于RV用的越来越多,就用RecyclerView吧。
布局
主布局文件,一个RecyclerView即可:
<?xml version="1.0" encoding="utf-8"?><android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/id_recyclerview" android:layout_width="match_parent" android:layout_height="match_parent" />
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
item布局文件:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/item_bg" android:gravity="center"> <com.imooc.rvimageads.AdImageViewVersion1 android:id="@+id/id_iv_ad" android:layout_width="match_parent" android:layout_height="180dp" android:scaleType="matrix" android:src="@mipmap/grsm" android:visibility="gone" /> <TextView android:layout_margin="12dp" android:id="@+id/id_tv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="这是title" android:textSize="16dp" android:textStyle="bold" /> <TextView android:id="@+id/id_tv_desc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/id_tv_title" android:layout_marginLeft="12dp" android:layout_marginRight="12dp" android:layout_marginBottom="12dp" android:text="这是描述" /></RelativeLayout>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
很简单,先不用管
AdImageViewVersion1
类,这将是我们具体的实现类。
通过布局文件,可以看到,我们只使用了一个item布局文件,然后通过visible,gone控制展示不同形态。Activity
public class MainActivity extends AppCompatActivity { private RecyclerView mRecyclerView; private LinearLayoutManager mLinearLayoutManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mRecyclerView = findViewById(R.id.id_recyclerview); List<String> mockDatas = new ArrayList<>(); for (int i = 0; i < 100; i++) { mockDatas.add(i + ""); } mRecyclerView.setLayoutManager(mLinearLayoutManager = new LinearLayoutManager(this)); mRecyclerView.setAdapter(new CommonAdapter<String>(MainActivity.this, R.layout.item, mockDatas) { @Override protected void convert(ViewHolder holder, String o, int position) { if (position > 0 && position % 6 == 0) { holder.setVisible(R.id.id_tv_title, false); holder.setVisible(R.id.id_tv_desc, false); holder.setVisible(R.id.id_iv_ad, true); } else { holder.setVisible(R.id.id_tv_title, true); holder.setVisible(R.id.id_tv_desc, true); holder.setVisible(R.id.id_iv_ad, false); } } });}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
仅仅是设置数据了,Adapter这里用了
compile 'com.zhy:base-rvadapter:3.0.3'
- 1
你可以随便用一个你自己喜欢的Adapter封装类。
到这里,一个列表页就显示出来了,并且每隔6个会显示成图片。
不截图了,脑补下…
现在才正式开始实现。
自定义AdImageView
public class AdImageViewVersion1 extends AppCompatImageView { public AdImageViewVersion1(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } private RectF mBitmapRectF; private Bitmap mBitmap; private int mMinDy; @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mMinDy = h; Drawable drawable = getDrawable(); if (drawable == null) { return; } mBitmap = drawableToBitamp(drawable); mBitmapRectF = new RectF(0, 0, w, mBitmap.getHeight() * w / mBitmap.getWidth()); } private Bitmap drawableToBitamp(Drawable drawable) { if (drawable instanceof BitmapDrawable) { BitmapDrawable bd = (BitmapDrawable) drawable; return bd.getBitmap(); } int w = drawable.getIntrinsicWidth(); int h = drawable.getIntrinsicHeight(); Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, w, h); drawable.draw(canvas); return bitmap; } // ... 省略一些代码}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
因为我们要绘制,所以这里我们把drawable转成bitmap,然后我们默认要显示最底部,所以需要一个最小的偏移,即控件高度。
这些事情,我们都在onSizeChanged做了。
并且我们根据当前控件宽度,对bitmap进行了缩放,并将缩放后的尺寸存在了mBitmapRectF中,以便于绘制。
那么接下来就是绘制了,还记得绘制过程中,我们主要利用translate来控制绘制的区域,所以我们还要对外暴露一个setDy方法,so,我们的代码大致是这样的:
private int mDy;public void setDy(int dy) { if (getDrawable() == null) { return; } mDy = dy - mMinDy; if (mDy <= 0) { mDy = 0; } if (mDy > mBitmapRectF.height() - mMinDy) { mDy = (int) (mBitmapRectF.height() - mMinDy); } invalidate();}@Overrideprotected void onDraw(Canvas canvas) { if (mBitmap == null) { return; } canvas.save(); canvas.translate(0, -mDy); canvas.drawBitmap(mBitmap, null, mBitmapRectF, null); canvas.restore();}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
setDy的时候,我们做了一个边界判断,最小的情况,我们偏移-mMinDy,显示图片的底部。
最大的时候,我们便宜图片高度-mMinDy,显示顶部部分。所以我们对传入的值做了最小与最大值判断。
那么在绘制的时候,就简单了,先translate dy距离,然后绘制即可。
到这里我们的自定义View部分就结束了,代码很少~
结合RecyclerView
接下来就是在RecyclerView滚动时,给我们传入dy即可。
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); int fPos = mLinearLayoutManager.findFirstVisibleItemPosition(); int lPos = mLinearLayoutManager.findLastCompletelyVisibleItemPosition(); for (int i = fPos; i <= lPos; i++) { View view = mLinearLayoutManager.findViewByPosition(i); AdImageViewVersion1 adImageView = view.findViewById(R.id.id_iv_ad); if (adImageView.getVisibility() == View.VISIBLE) { adImageView.setDy(mLinearLayoutManager.getHeight() - view.getTop()); } } }});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
通过addOnScrollListener监听,当滚动时,拿到所有可见的Item,找出正在显示图片的Item。然后调用setDy,dy的值为
mLinearLayoutManager.getHeight() - view.getTop()
,当View从最底部出现的时候为0,当View到达最顶部的时候为当前rv的高度。你可以合理的利用setDy传入的值,做移动差,显示区域从上到下等,都可以。
这样就完成了~~
一句话实现:即滚动时不断改变dy,然后translate绘制即可。
四、再想想
看着这个代码,好像
drawableToBitamp
看起来非常不爽,也是比较耗内存的部分。我们再想想:本身Drawable就是能绘制的,为什么我们要转成bitmap呢?
好像有道理,ImageView本身绘制的就是Drawable,我们需要控制的就是这个Drawable的绘制范围要足够大,不能被控件本身的宽高所影响,导致图片被压扁。
好像有那么一个方法:
drawable.setBounds();
- 1
那就简单了,去除drawable2bitmap的代码,直接利用原本的绘制即可,我们唯一要做的就是设置bounds,做一个translate dy即可。
完整代码:
public class AdImageView extends AppCompatImageView { // 删除构造方法 private int mDx; private int mMinDx; public void setDx(int dx) { if (getDrawable() == null) { return; } mDx = dx - mMinDx; if (mDx <= 0) { mDx = 0; } if (mDx > getDrawable().getBounds().height() - mMinDx) { mDx = getDrawable().getBounds().height() - mMinDx; } invalidate(); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mMinDx = h; } public int getDx() { return mDx; } @Override protected void onDraw(Canvas canvas) { Drawable drawable = getDrawable(); int w = getWidth(); int h = (int) (getWidth() * 1.0f / drawable.getIntrinsicWidth() * drawable.getIntrinsicHeight()); drawable.setBounds(0, 0, w, h); canvas.save(); canvas.translate(0, -getDx()); super.onDraw(canvas); canvas.restore(); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
短短的代码就实现了,这样看起来顺眼多了~~
再贴下效果图:
效果图主要看字,你懂的!
好了,本篇总结:
看到当看一个效果,可以先对它进行拆分,找出关键点,针对每个关键点,考虑可行性。
如果确定每个点都可行,那么基本的方案就出来了。
有了基本的方案,不要着急写,再想想还有无改善空间。
例子比较简单,have a nice day ~~
再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow
-
创意广告大考验活动策划书.doc
2020-12-26 20:07:56创意广告大考验活动策划书 活动主题:创意广告大考验 活动时间:12月7号(初赛) 12月9号(决赛) 活动地点:a楼407教室(初赛)a楼412教室(决赛) 主办单位:中文系团委 协办单位: 媒介教育协会 活动背景及... -
最新冰淇淋创意广告语_精选.doc
2020-12-03 16:27:09最新冰淇淋创意广告语 冰淇淋是孩童时代最好的零食食品,特别是在夏天能够尝上一口冰淇淋,体现夏天的冰凉,那么关于冰淇淋的广告语有哪些可以吸引顾客购买呢,下面一起来看下吧。 最新冰淇淋创意广告语 1. 爱上爱... -
经典美甲创意广告宣传标语_精选.doc
2020-12-03 16:27:09经典美甲创意广告宣传标语 随着人们对于美的追求越来越高,美甲店已经深入到爱美女性的生活当中。下面是小编为大家精心推荐的经典美甲创意广告语,希望能够对您有所帮助。 经典美甲创意广告宣传标语 1. 指尖上的... -
女鞋创意广告宣传标语_精选.doc
2020-12-03 16:30:11女鞋创意广告宣传标语 行走中的时尚,智慧女人的选择。下面是的小编为你们整理的内容,希望你们能够喜欢 女鞋创意广告语 1、休闲时刻,自由选择。 2、温暖在心,好鞋在行。 3、最美不过岁月,最长只是脚步。 4... -
大学生创意广告剪辑大赛策划书.doc
2021-01-15 13:21:15大学生创意广告剪辑大赛策划书 一、活动主题:大学生创意广告剪辑大赛 二、活动口号:数码科技展翅未来,由你缔造全新经典广告 三、活动目的: 通过本次大学生创意广告剪辑大赛,培养同学们对电脑软件应用的兴趣... -
环保灯的创意广告词大全_关于环保的广告语10个
2020-12-03 16:27:11环保灯的创意广告词大全 环保灯相关的广告词要基于长远的销售利益,向消费者传达一种长期不变的观念。以下是小编为大家带来的经典宣传语,欢迎大家参考! 热门环保灯的经典广告词 1. 严格控管生产流程,xx给您质量... -
2019中秋月饼销售创意广告语大全_精选.doc
2020-12-03 16:27:082019中秋月饼销售创意广告语大全 中秋节到了,月饼也开始走进每家每户,那么有哪些关于月饼销售的广告创意语句呢,下面小编整理关于“2019中秋月饼销售创意广告语大全”的内容,欢迎大家阅读。 2019中秋月饼销售... -
洗发水英文创意广告词_精选.doc
2020-12-03 16:27:33洗发水英文创意广告词 我们熟知许多洗发水的广告,有些广告里面的广告词现在还能朗朗上口,洗发水的广告多不胜数,那么英文版的广告词你知道多少?下面是小编带来的内容,欢迎阅读! 洗发水英文广告词举例 1. ... -
保险公司的创意广告词大全_精选.doc
2020-12-03 16:27:12保险公司的创意广告词大全 广告语的创意是一项需要灵感与不断创新工作,保险公司的广告语的文体形式并无定式,那就需要从业者在具体工作中不断创造和完善。下面小编为大家带来的广告词,欢迎大家参考! 保险公司的... -
女装英文创意广告语大全_精选.doc
2020-12-03 16:27:32女装英文创意广告语大全 女装的品牌多得数不胜数,广告经营成功可以帮品牌杀出重围。广告语的创作是一项需要灵感与不断创新工作,广告语的文体形式并无定式,需要从业者在具体工作中不断创造和完善。下面是小编带来... -
时尚女包的创意广告词大全_精选.doc
2020-12-03 16:27:17时尚女包的创意广告词大全 一个经过精心选择的包包会在时尚上具有画龙点睛的作用,它能将你装饰成真正的女白领。以下是小编为大家带来的创意广告词,欢迎大家参考! 热门时尚女包的创意广告词 1. 包容天地,内有... -
汽车4S店形象创意广告语_精选.doc
2020-12-03 16:27:19汽车4S店形象创意广告语 进入21世纪,汽车走入千家万户的生活,成为人民日常出行代步的交通工具。下面是小编为大家精心推荐的4s店创意广告语,希望能够对您有所帮助。 汽车4S店形象创意广告语 1. 奥迪每一步,滨奥心...
-
【Pytorch】Softmax激活函数
-
华为1+X认证——网络系统建设与运维(初级)
-
2021-03-03
-
信息学奥赛一本通-教程PPT课件(第五版)算法部分 第五章 搜索与回溯算法.pdf
-
信息学奥赛一本通-教程PPT课件(第五版)算法部分 第二章 数据排序.pdf
-
基于微信的同城小程序、校园二手交易小程序 毕业设计毕设源码使用教程
-
Java多线程(4)-Thread的生命周期
-
Windows系统管理
-
ch_calendar.xls
-
基于Qt的LibVLC开发教程
-
Eclipse学生信息管理系统.rar
-
MobaXterm_Installer_v20.4.zip
-
2021年熔化焊接与热切割考试资料及熔化焊接与热切割复审考试
-
记录过程的步骤.zip
-
pytorch中BatchNorm1d、BatchNorm2d、BatchNorm3d
-
MHA 高可用 MySQL 架构与 Altas 读写分离
-
【布道者】Linux极速入门
-
vscode和微信开发者工具代码同步更新(vue)
-
2021.3.3学习总结
-
1.2.8小说源码.zip