最近在我三星手机上看到了很有意思的图片广告,听说是模仿知乎创意广告。来回看了看,觉得挺有意思,就开始动手写写这个小效果。很简单,一点也不难实现。不多说,先上图:
直接贴代码,不懂看注释:
1、重写ImageView
/**
* Created by csc on 2018/1/24.
* explain:
*/
public class AdsImagView extends ImageView {
public AdsImagView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
//广告位的高度
private int imgvHeight;
//显示比率
private float rate=1;
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//设置广告位的高度
imgvHeight=h;
}
@Override
protected void onDraw(Canvas canvas) {
//获得画板
Drawable drawable=getDrawable();
//getIntrinsicWidth()和getIntrinsicHeight(),顾名思义他们是用来取得Drawable的固有的宽度和高度
// w/getIntrinsicWidth()=y/getIntrinsicHeight()
int w=getWidth();
int h= (int) (w*1.0f/drawable.getIntrinsicWidth()*drawable.getIntrinsicHeight());
//设置图片的显示范围
drawable.setBounds(0,0,w,h);
//表示图片可移动的的最大范围
int maxDy=h-imgvHeight;
canvas.save();
//图片的纵向位移
canvas.translate(0,-maxDy*rate);
super.onDraw(canvas);//这里注意:为什么super写在这里,因为如果先画再super就会把我们画的给挡住。
canvas.restore();
}
//设置图片的位移(条目距离顶部的距离,rv的高度)
public void setDy(int distanceTop,int rvHeight){
//广告位有效滚动的距离
int canHeight=rvHeight-distanceTop;
//求出滚动的比率
rate=distanceTop*1.0f/canHeight;
if (rate<=0){
rate=0;
}
if (rate>=1){
rate=1;
}
invalidate();
}
}
2、RecyclerView的条目布局;
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.youyu.zhihuads.AdsImagView
android:src="@drawable/beautiful"
android:id="@+id/imgv"
android:layout_width="match_parent"
android:layout_height="150dp"
android:scaleType="matrix" />
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/imgv"
android:gravity="center"
android:text="条目"
android:textSize="20sp" />
</RelativeLayout>
3、监听Rv的位移,设置ImgeView位移
public class MainActivity extends AppCompatActivity {
private RecyclerView mRv;
private List<String> lists=new ArrayList<>();
private RvAdapter mAdapter;
private LinearLayoutManager lineatLayoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lineatLayoutManager=new LinearLayoutManager(this);
for (int i = 0; i < 50; i++) {
lists.add("我是新闻第:"+i+"条");
}
mRv = (RecyclerView) findViewById(R.id.rv);
mRv.setLayoutManager(lineatLayoutManager);
mAdapter=new RvAdapter(lists);
mRv.setAdapter(mAdapter);
//设置Rv的滚动监听
mRv.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
//第一个显示的条目
int fistVisible=lineatLayoutManager.findFirstVisibleItemPosition();
//最后一个显示的条目
int lastVisible=lineatLayoutManager.findLastVisibleItemPosition();
//从第一个显示条目 遍历到 最后一个显示的条目
for (int i = fistVisible; i <= lastVisible; i++) {
//根据位置找到控件
View view = lineatLayoutManager.findViewByPosition(i);
AdsImagView imgv=view.findViewById(R.id.imgv);
if (imgv.getVisibility()==View.VISIBLE){
//获取广告位的位置与Rv顶部的距离
int top=view.getTop();
//获取Rv的高度
int rvHeight=mRv.getHeight();
//设置广告的位移
imgv.setDy(top,rvHeight);
}
}
}
});
}
}
哈哈,这样就搞定,就是这么简单。