Android onDraw触发ImageView的setImageBitmap实现动画,可见时执行动画,不可见时自动停止动画

Android onDraw触发ImageView的setImageBitmap实现动画,可见时执行动画,不可见时自动停止动画

一个简单的小例子,这个例子首先从assets读取出若干张图片作为Bitmap资源,然后在onDraw里面每个25ms触发一次ImageView的setImageBitmap,这样做以25ms作为周期,循环的每隔25ms重新设置ImageView的图片源,达到动画效果,这样做的好处是,由于onDraw只在可见状态下重绘才调用,如果当前的自定义的ImageView不可见,自动就停止执行动画,比较节能。

package zhangphil.test;

import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;
import android.util.Log;

import java.io.InputStream;

public class LoadingImageView extends AppCompatImageView {
    private String TAG = "加载动画";
    private Context mContext;
    private Bitmap[] mBitmaps;

    private int i = 0;
    private int WHAT = 0xfc01;

    /**
     * 是否执行动画,如果为false,不需要动画逻辑。
     * 默认true执行。
     */
    private boolean mAnimationEnable = true;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == WHAT) {
                mHandler.removeMessages(WHAT);

                //Log.d(TAG, "设置新动画图片");
                setImageBitmap(mBitmaps[i++ % mBitmaps.length]);
            }
        }
    };

    public LoadingImageView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);

        mContext = context;
        init();
    }

    /**
     * true,当该View可见状态下就执行动画。
     * false,当前View无论处于何种状态都不执行动画。
     *
     * @param enable
     */
    public void setAnimationEnable(boolean enable) {
        mAnimationEnable = enable;
    }

    private void init() {
        mBitmaps = getBimaps();
        if (!isResOk()) {
            Log.e(TAG, "动画资源为空!");
            return;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //Log.d(TAG, "onDraw");

        if (mAnimationEnable && isResOk()) {
            mHandler.sendEmptyMessageDelayed(WHAT, 25);
        }
    }

    private boolean isResOk() {
        return mBitmaps != null && mBitmaps.length > 0;
    }

    /**
     * 从assets目录下读取图片资源放到数组里面,作为连续动画的资源图。
     *
     * @return
     */
    private Bitmap[] getBimaps() {
        final String parentPath = "loading";

        Bitmap[] bitmaps = null;
        AssetManager am = mContext.getAssets();
        try {
            String[] files = am.list(parentPath);
            bitmaps = new Bitmap[files.length];
            for (int i = 0; i < files.length; i++) {
                InputStream is = am.open(parentPath + "/" + files[i]);
                bitmaps[i] = BitmapFactory.decodeStream(is);
                is.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return bitmaps;
    }
}

使用方法和普通的ImageView一样,这个自定义LoadingImageView比较适合下拉刷新时候头部的滚动圆球动画制作和实现。

出于兼容高版本的目的,在上层Java代码主动调用一次动画的start方法触发动画:

        ImageView mImageView = findViewById(R.id.load_image);
        AnimationDrawable mAnimationDrawable = (AnimationDrawable) mImageView.getDrawable();
        mAnimationDrawable.start();

因为代码需要从assets目录下的loading目录下读取图片作为动画素材,因此需要事先在项目的assets目录下放置一系列要连续加载的图片。

发布了1031 篇原创文章 · 获赞 989 · 访问量 337万+
展开阅读全文

怎么在自定义ImageView上Draw东西,然后获取为Bitmap?

01-29

public class MainActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); View view= View.inflate(this,R.layout.activity_main,null); //布局参数 ViewGroup.LayoutParams layoutParams=new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); ImageView imageView=new ImageView(this); //设置布局参数 imageView.setLayoutParams(layoutParams); imageView.setBackgroundColor(Color.RED); //把textview加入RelativeLayout中 ((RelativeLayout)view).addView(imageView); //显示整个布局 setContentView(view); setContentView(new SmileyView(this)); } } class SmileyView extends View { private Paint mCirclePaint; private float mCenterX; private float mCenterY; private float mRadius; public SmileyView(Context context) { this(context, null); } public SmileyView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public SmileyView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initPaints(); } private void initPaints() { mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mCirclePaint.setStyle(Paint.Style.FILL); mCirclePaint.setColor(Color.YELLOW); } protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int w = MeasureSpec.getSize(widthMeasureSpec); int h = MeasureSpec.getSize(heightMeasureSpec); int size = Math.min(w, h); setMeasuredDimension(size, size); } protected void onSizeChanged(int w, int h, int oldw, int oldh) { mCenterX = w / 2f; mCenterY = h / 2f; mRadius = Math.min(w, h) / 2f; } protected void onDraw(Canvas canvas) { canvas.drawCircle(mCenterX, mCenterY, mRadius, mCirclePaint); // draw eyes } } 上面这个代码如何修改为在ImageView上显示画的圆,然后把ImageView转化成Bitmap?麻烦具体点,我小白 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 深蓝海洋 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览