1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Android基础控件——ImageView的自定义 再次利用Matrix完美模仿小红书长图自动滚动效果

Android基础控件——ImageView的自定义 再次利用Matrix完美模仿小红书长图自动滚动效果

时间:2021-10-21 14:00:26

相关推荐

Android基础控件——ImageView的自定义 再次利用Matrix完美模仿小红书长图自动滚动效果

前言

当我们阅读了ImageView源码后,发现Matrix的使用真的是很强大,几乎可以实现我们很多该有的功能,当我第一次看到这个效果的时候,第一想法就是ImageView的Matrix。通过比对了网上很多方案后,网上的方案还是比较复杂,如果我们巧用Matrix去做效果时,会发现其实代码也就100行左右就完美实现了效果,而且性能方面很不错,由于Gif图效果不佳,建议用代码跑一遍

效果展示

实现思路

我们的思想思路就是将两面相同的长图拼接成一张长图,通过平移播放这张长图,当我们的长图滑动到第二面图片的顶部时候,此时屏幕的顶部刚好和第二面图顶部相连接,这时候,我们马上将图片移到第一面,通过无缝的快速移动,骗过眼睛,实现我们自动滚动的效果,此时又重新从第一面开始滚动,如此循环就形成了自动滚动效果

准备工作

准备好一张长图将两张同样的长图通过工具合成一张长图开始撸代码

合成前的长图

合成后的长图

实现步骤

1、快速使用

在xml直接配置的形式即可

<com.remo.mobile.framework.widget.ScrollerImageViewandroid:layout_width="match_parent"android:layout_height="match_parent"app:autoScroller="true"app:scrollerImage="@drawable/login_bg_scroller_picture" />

2、自定义属性

<resources><declare-styleable name="ScrollerImageView"><attr name="scrollerImage" format="reference" /><attr name="autoScroller" format="boolean" /></declare-styleable></resources>

3、定义属性

public class ScrollerImageView extends AppCompatImageView {private Bitmap mBitmap; //当前滚动的图片private Boolean autoScroller; //是否自动滚动private int speed = 10; //当前滚动的速度private float scale = 1f; //当前图片需要放大的比例private double scrollerY = 0f; //当前滚动的Y坐标private double onePictureHeight = 0; //一张图片的高度public ScrollerImageView(Context context) {this(context, null);}public ScrollerImageView(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public ScrollerImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initTypeArray(context, attrs);}}

4、获取自定义属性

private void initTypeArray(Context context, AttributeSet attrs) {final TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ScrollerImageView);int resId = typedArray.getResourceId(R.styleable.ScrollerImageView_scrollerImage, -1);autoScroller = typedArray.getBoolean(R.styleable.ScrollerImageView_autoScroller, false);mBitmap = BitmapFactory.decodeResource(context.getResources(), resId);typedArray.recycle();}

5、更新尺寸和自动播放

onSizeChanged回调中,去更新我们的界面和开始滚动播放,由于我们的图片不一定是宽度充满整个屏幕,所以我们需要先缩放整个图片,通过updateCropMatrix缩放,接着通过runnable一直平移

@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);updateCropMatrix();if (autoScroller) {startScroller();}}private void updateCropMatrix() {if (mBitmap == null) return;setImageBitmap(mBitmap);setScaleType(ScaleType.MATRIX);Matrix mMatrix = new Matrix();final int vHeight = getHeight() - getPaddingLeft() - getPaddingRight();//获取真实高度final int vWidth = getWidth() - getPaddingTop() - getPaddingBottom();//获取真实宽度final int dWidth = mBitmap.getWidth();final int dHeight = mBitmap.getHeight();scale = (float) vWidth / (float) dWidth;onePictureHeight = (mBitmap.getHeight() * scale) / 2; //获取一面图片的高度mMatrix.setScale(scale, scale); //先将图片宽缩放到View的同等大小setImageMatrix(mMatrix);}private Runnable scrollerRunnable = new Runnable() {@Overridepublic void run() {Matrix matrix = getImageMatrix();if (scrollerY >= onePictureHeight) {//当前刚好到第二面顶部,里面平移回去到第一面matrix.postTranslate(0, (float) onePictureHeight);scrollerY = 0;} else {matrix.postTranslate(0, -1);scrollerY++;}setImageMatrix(matrix);invalidate();getHandler().postDelayed(this, speed);}};private void startScroller() {removeCallbacks(scrollerRunnable);postDelayed(scrollerRunnable, speed);}

6、释放内存

@Overrideprotected void onDetachedFromWindow() {super.onDetachedFromWindow();stopScroller();mBitmap.recycle();mBitmap = null;}

7、源码

public class ScrollerImageView extends AppCompatImageView {private Bitmap mBitmap; //当前滚动的图片private Boolean autoScroller; //是否自动滚动private int speed = 10; //当前滚动的速度private float scale = 1f; //当前图片需要放大的比例private double scrollerY = 0f; //当前滚动的Y坐标private double onePictureHeight = 0; //一张图片的高度public ScrollerImageView(Context context) {this(context, null);}public ScrollerImageView(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public ScrollerImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initTypeArray(context, attrs);}private void initTypeArray(Context context, AttributeSet attrs) {final TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ScrollerImageView);int resId = typedArray.getResourceId(R.styleable.ScrollerImageView_scrollerImage, -1);autoScroller = typedArray.getBoolean(R.styleable.ScrollerImageView_autoScroller, false);mBitmap = BitmapFactory.decodeResource(context.getResources(), resId);typedArray.recycle();}private void updateCropMatrix() {if (mBitmap == null) return;setImageBitmap(mBitmap);setScaleType(ScaleType.MATRIX);Matrix mMatrix = new Matrix();final int vHeight = getHeight() - getPaddingLeft() - getPaddingRight();//获取真实高度final int vWidth = getWidth() - getPaddingTop() - getPaddingBottom();//获取真实宽度final int dWidth = mBitmap.getWidth();final int dHeight = mBitmap.getHeight();scale = (float) vWidth / (float) dWidth;onePictureHeight = (mBitmap.getHeight() * scale) / 2;mMatrix.setScale(scale, scale); //先将图片宽缩放到View的同等大小setImageMatrix(mMatrix);}private Runnable scrollerRunnable = new Runnable() {@Overridepublic void run() {Matrix matrix = getImageMatrix();if (scrollerY >= onePictureHeight) {matrix.postTranslate(0, (float) onePictureHeight);scrollerY = 0;} else {matrix.postTranslate(0, -1);scrollerY++;}setImageMatrix(matrix);invalidate();getHandler().postDelayed(this, speed);}};private void startScroller() {removeCallbacks(scrollerRunnable);postDelayed(scrollerRunnable, speed);}private void stopScroller() {removeCallbacks(scrollerRunnable);}@Overrideprotected void onDetachedFromWindow() {super.onDetachedFromWindow();stopScroller();mBitmap.recycle();mBitmap = null;}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);updateCropMatrix();if (autoScroller) {startScroller();}}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。