怎么让我们的长图片不用滑动而自己动起来呢?
效果图(在手机上运行会流畅很多):
思路:
1.自定义一个图片呈现控件继承view;
2.我们先得到控件的宽度controlWidth,和图片的宽度bitmapWidth,图片移动距离初始值为0;
3.每隔1毫秒移动一次偏移量,然后重新绘制图片;
4.从源图片上截取减去偏移量显示在控件上的图片部分生成一张新的图片绘制到画布上;
5,如果图片减去偏移量的部分不足以填充整个控件,则剩余部分在画布上从源图片的开始从新画。
6.当偏移量和图片宽度相等时,偏移量置0,以实现不断循环的效果。
代码分析:
package com.example.image; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.Log; import android.view.View; /** * Created by pactera on 2017/4/18. */ public class LongCircleImageView extends View { /**图片的高度*/ private int bitmapHeight; /**图片的宽度*/ private int bitmapWidth; /**控件的高度*/ private int Width; /**控件的宽度*/ private int Height; /**图片源*/ private Bitmap source; /**移动的偏移量*/ private int offset; /**是否继续移动*/ private boolean canMove = false; /**刷新handler*/ private Handler refreshHandler = new Handler() { @Override public void handleMessage(Message msg) { invalidate(); } }; /**移动速度单位*/ private static final int speedUnit = 5; public LongCircleImageView(Context context) { super(context); initView(); } public LongCircleImageView(Context context, AttributeSet attrs) { super(context, attrs); initView(); } public LongCircleImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(); } private void initView() { source = BitmapFactory.decodeResource(getResources(), R.drawable.timg); bitmapHeight = source.getHeight();//获取图片的高度 bitmapWidth = source.getWidth();//获取图片的宽度 canMove = true; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); Width = MeasureSpec.getSize(widthMeasureSpec); Height = MeasureSpec.getSize(heightMeasureSpec); //当控件的宽高都是wrap_content时,设置控件宽高为图片宽高 if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.AT_MOST && MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) { Width = bitmapWidth; Height = bitmapHeight; setMeasuredDimension(Width, Height); } else {//根据设置的控件宽高缩放图片,以便图片可以在控件中完全显示,不会出现控件太小而显示不全图片的情况 BitmapFactory.Options opts = new BitmapFactory.Options(); opts.inSampleSize = Math.max(bitmapWidth/Width, bitmapHeight/Height); source.recycle(); source = BitmapFactory.decodeResource(getResources(), R.drawable.timg, opts); } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); bitmapWidth = source.getWidth(); bitmapHeight = source.getHeight(); if (offset >= bitmapWidth) {//如果便宜量大于图片宽度,则偏移量置0,以实现图片无限循环播放 offset = 0; } //如果图片宽度减去偏移量还是大于控件宽度,则新构建的图片宽度为控件宽度,否则宽度就是图片宽度减去偏移量 int width = bitmapWidth - offset > Width ? Width : bitmapWidth - offset; Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); //构建一幅以source为原图,从偏移位置到图片宽度截取到的一幅新的图片 Bitmap bitmap = Bitmap.createBitmap(source, offset, 0, width, bitmapHeight); //将新图片从控件的左侧和控件的顶部开始画到画布上 canvas.drawBitmap(bitmap,0, 0, paint); //如果图片宽度减去偏移量不足以覆盖整个控件,则从图片宽度减去偏移量的位置开始重新把原图画到画布上 if (bitmapWidth - offset <= Width) { canvas.drawBitmap(source,bitmapWidth - offset, 0, paint); } offset += speedUnit;//根据移动速度单位修改偏移量 if (canMove)//是否可以移动 refreshHandler.sendEmptyMessageDelayed(0,1);//每隔1毫秒刷新一次界面 } /**暂停后回复移动*/ public void resume() { canMove = true; } /**暂停移动*/ public void pause() { canMove = false; } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if (source != null) { source.recycle(); source = null; } } }