- 捕获列表滚动的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”
/>
item布局文件:
<?xml version="1.0" encoding="utf-8"?><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” />
很简单,先不用管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 mockDatas = new ArrayList<>();
for (int i = 0; i < 100; i++) {
mockDatas.add(i + “”);
}
mRecyclerView.setLayoutManager(mLinearLayoutManager = new LinearLayoutManager(this));
mRecyclerView.setAdapter(new CommonAdapter(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);
}
}
});
}
仅仅是设置数据了,Adapter这里用了
compile ‘com.zhy:base-rvadapter:3.0.3’
你可以随便用一个你自己喜欢的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;
}
// … 省略一些代码
}
因为我们要绘制,所以这里我们把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();
}
@Override
protected void onDraw(Canvas canvas) {
if (mBitmap == null) {
return;
}
canvas.save();
canvas.translate(0, -mDy);
canvas.drawBitmap(mBitmap, null, mBitmapRectF, null);
canvas.restore();
}
最后
今天关于面试的分享就到这里,还是那句话,有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。
最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司20年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
【Android核心高级技术PDF文档,BAT大厂面试真题解析】
【算法合集】
【延伸Android必备知识点】
也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
【Android核心高级技术PDF文档,BAT大厂面试真题解析】
[外链图片转存中…(img-G8gDw1ry-1719207519234)]
【算法合集】
[外链图片转存中…(img-7KQvbG0D-1719207519235)]
【延伸Android必备知识点】
[外链图片转存中…(img-IXOKzWxR-1719207519235)]