仿知乎的廣告欄學(xué)習(xí)
Screenshot_2019-05-25-16-08-00.png
Screenshot_2019-05-25-16-08-04.png
Screenshot_2019-05-25-16-08-07.png
Screenshot_2019-05-25-16-32-09.png
思路
自定義View 繼承自imgView
然后通過(guò)canvas 對(duì)圖片進(jìn)行局部繪制
進(jìn)行局部的繪制就需要獲取itemview的位置
Activity的代碼
import android.databinding.DataBindingUtil;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import com.chen.testapplciation.R;
import com.chen.testapplciation.databinding.ActivityRvAdvertisementBinding;
public class Rv_advertisement extends AppCompatActivity {
ActivityRvAdvertisementBinding binding;
LinearLayoutManager mLinearLayoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLinearLayoutManager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
binding = DataBindingUtil.setContentView(this,R.layout.activity_rv_advertisement);
binding.rvAdvertisement.setAdapter(new MyAdapter());
binding.rvAdvertisement.setLayoutManager(mLinearLayoutManager);
binding.rvAdvertisement.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int fpos = mLinearLayoutManager.findFirstVisibleItemPosition();
int lpos =mLinearLayoutManager.findLastVisibleItemPosition();
for (int i = fpos; i < lpos; i++) {
View view = mLinearLayoutManager.findViewByPosition(i);
AdimageView adimageView = view.findViewById(R.id.img_av);
if (adimageView != null){
adimageView.setTextView(binding.textMdy);
int dy1 = mLinearLayoutManager.getHeight() - view.getTop();
binding.textDy.setText("itemview頂部到底部的高"+dy1+" \n" + "recyclerview=" +mLinearLayoutManager.getHeight() + " \n"+"圖片item到頂部的距離"+view.getTop());
adimageView.setDy(dy1);
}
}
}
});
}
}
我直接用的 databinding
來(lái)獲取Recycleview
layout 為了理清思路 我把一些參數(shù)顯示出來(lái)
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".donghua.Rv_advertisement">
<data>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:id="@+id/text_dy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="10sp"
android:text="0"
android:gravity="center"/>
<TextView
android:id="@+id/text_mdy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="10sp"
android:text="0"
android:gravity="center"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_advertisement"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
</layout>
adapter
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.chen.testapplciation.R;
import java.util.ArrayList;
public class MyAdapter extends RecyclerView.Adapter {
ArrayList<String> data = new ArrayList<>();
@Override
public int getItemViewType(int position) {
if (position%10 ==0){
return 1;
}
return 0;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
if (i ==0){
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.rv_item_textview,viewGroup,false);
return new ViewHolder(view);
}else {
View view =LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.rv_item_advertisement,viewGroup,false);
return new AdtViewHolder(view);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
AdimageView adimageView = viewHolder.itemView.findViewById(R.id.img_av);
if (adimageView != null){
adimageView.setnotvisible();
}
}
@Override
public int getItemCount() {
return 100;
}
static class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(@NonNull View itemView) {
super(itemView);
}
}
static class AdtViewHolder extends RecyclerView.ViewHolder {
public AdtViewHolder(@NonNull View itemView) {
super(itemView);
}
}
}
adapter 就兩個(gè)Viewholder
一種顯示圖片
一種顯示文字
onBindViewHolder
因?yàn)?code>recyclerview復(fù)用viewholder
鲫惶。所以一定 要初始化一下viewholder
倆個(gè)viewholder的layout
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="200dp">
<com.chen.testapplciation.donghua.AdimageView
android:id="@+id/img_av"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/nav_bc_0"
android:scaleType="centerCrop"
/>
</FrameLayout>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="100dp">
<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>
其中adimgview 就是自定義的view
Adimgview代碼
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView;
public class AdimageView extends AppCompatImageView {
private RectF mBitmapRectF;
private Bitmap mBitmap;
private TextView mTextView;
private int mMinDy = 0;
public void setTextView(TextView textView) {
mTextView = textView;
}
public AdimageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
int showwidth;
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
showwidth = w;
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;
}
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);
}
mTextView.setText("繪制偏移量"+mDy+"\n "+"imgageview顯示的高度=" +mMinDy +"\n"+" 圖片的縮小后的高度"+height );
invalidate();
}
int bitmapheight ;
int bitmapwidth ;
int height =0;
public void setnotvisible() {
mDy =0;
}
@Override
protected void onDraw(Canvas canvas) {
if (mBitmap == null) {
return;
}
bitmapheight = mBitmap.getHeight();
bitmapwidth= mBitmap.getWidth();
height = bitmapheight *showwidth/bitmapwidth;
canvas.save();
canvas.translate(0,-mDy);
canvas.drawBitmap(mBitmap, null, mBitmapRectF, null);
canvas.restore();
}
}
再梳理一下過(guò)程
在Activity中給recyclerview的LinearLayoutManager 綁定一個(gè)監(jiān)聽(onScroollListener()
)班挖,
監(jiān)聽滾動(dòng)
找到可顯示的item中的 有 AdimgView的item窖梁,然后recyclerview的高度減去itemview頂部的高度得到
itemview頂部到底部的高度捣作,
將次高度傳入adimgview中
這個(gè)高度減去adimgview自身的高度。就是canvas 作圖的偏移量
然后通過(guò)這個(gè)偏移量canva 畫出bitmap任意的一部分內(nèi)容