Android 自定义View修炼-自定义加载进度动画LoadingImageView

一、概述

本自定义View,是加载进度动画的自定义View,继承于ImageView来实现,主要实现蒙层加载进度的加载进度效果。

支持水平左右加载和垂直上下加载四个方向,同时也支持自定义蒙层进度颜色。

直接看下面的效果图吧。

二、效果图

废话不说,先来看看效果图吧~~

三、实现原理方案

1、自定义View-XCLoadingImageView,继承ImageVIew来实现,这样就不用自己再处理drawable和测量的工作内容。

2、根据蒙层颜色创建一个蒙层bitmap,然后根据这个bitmap来创建一个ClipDrawable,最后利用ClipDrawable的level属性

来裁剪显示区域进度,从而达到加载进度的效果。

3、最后利用属性动画技术或ClipDrawable的setLevel()方法来达到进度的效果。

四、自定义加载进度效果XCLoadingImageView的具体实现

1、初始化需要用到的数据变量以及画笔以及属性

private Paint mImagePaint;
    private int mImageHeight, mImageWidth;
    private boolean mIsAutoStart = false;
    private int mMaskColor = Color.TRANSPARENT;
    private ClipDrawable mClipDrawable;
    private Drawable mMaskDrawable;
    private int maskHeight;
    private int mProgress;
    private ObjectAnimator mAnimator;
    private long mAnimDuration = 2500;
    private float mScaleX, mScaleY;
    private int mGravity = Gravity.BOTTOM;
    private int mOrientaion = ClipDrawable.VERTICAL;
    private int mMaskOrientation = MaskOrientation.BottomToTop;

    //Loading oriention
    public static final class MaskOrientation {
        public static final int LeftToRight = 1;
        public static final int RightToLeft = 2;
        public static final int TopToBottom = 3;
        public static final int BottomToTop = 4;
    }

/**
     * initial attributes
     */
    private void initAttrs(Context context, AttributeSet attrs) {
        if (attrs == null) {
            return;
        }
        TypedArray t = context.obtainStyledAttributes(attrs, R.styleable.XCLoadingImageView);
        mMaskColor = t.getColor(R.styleable.XCLoadingImageView_mask_color, mMaskColor);
        mIsAutoStart = t.getBoolean(R.styleable.XCLoadingImageView_auto_start_anim, mIsAutoStart);
        setMaskColor(mMaskColor);
        t.recycle();
    }

    /**
     * initial paint
     */
    private void init() {
        if (mImagePaint == null) {
            mImagePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mImagePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
        }
    }

2、初始化蒙层Bitmap以及创建加载进度用的ClipDrawable

private void initMaskBitmap(int maskColor) {    Drawable drawable = getDrawable();    if (drawable == null) {        return;    }    Bitmap bgBmp = ((BitmapDrawable) drawable).getBitmap();    mImageWidth = drawable.getIntrinsicWidth();    mImageHeight = drawable.getIntrinsicHeight();

    Bitmap fgBmp = Bitmap.createBitmap(mImageWidth, mImageHeight, Bitmap.Config.ARGB_8888);    Canvas fgCanvas = new Canvas(fgBmp);    fgCanvas.drawColor(maskColor);

    Bitmap bitmap = combineBitmap(bgBmp, fgBmp);    mMaskDrawable = new BitmapDrawable(null, bitmap);    mClipDrawable = new ClipDrawable(mMaskDrawable, mGravity, mOrientaion);}

3、合并蒙层Bitmap和ImageView的src的drawable为新的Bitmap 

/** * combine tow bitmap to one bitmap */private Bitmap combineBitmap(Bitmap bg, Bitmap fg) {    Bitmap bmp = Bitmap.createBitmap(mImageWidth, mImageHeight, Bitmap.Config.ARGB_8888);    Canvas canvas = new Canvas(bmp);    canvas.drawBitmap(bg, 0, 0, null);    canvas.drawBitmap(fg, 0, 0, mImagePaint);    return bmp;}

4、重写ImageVIew的onDraw()方法来把创建的ClipDrawable绘制到Canvas上

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    canvas.save();    canvas.scale(mScaleX, mScaleY);    mClipDrawable.setBounds(getDrawable().getBounds());    mClipDrawable.draw(canvas);    canvas.restore();}
 

5、弹通过属性动画或者setLevel,并调用postInvalidate()来重绘,从而达到进度刷新的效果

private void initAnim() {    stopAnim();    mAnimator = ObjectAnimator.ofInt(mClipDrawable, "level", 0, 10000);    mAnimator.setDuration(mAnimDuration);    mAnimator.setRepeatCount(ValueAnimator.INFINITE);    mAnimator.setRepeatMode(ValueAnimator.RESTART);    mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {        @Override        public void onAnimationUpdate(ValueAnimator animation) {            postInvalidate();        }    });    if (mIsAutoStart) {        mAnimator.start();    }}public void setProgress(int progress){    mProgress = progress;    mClipDrawable.setLevel(mProgress * 100);    postInvalidate();}

五、如何使用该自定义LoadingView控件

1、使用该自定义LoadingView非常简单,和使用普通ImageView差不对哦,只需设置下方向和蒙层颜色即可

public class MainActivity extends Activity {

    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);

        XCLoadingImageView imageView2 = (XCLoadingImageView) findViewById(R.id.img2);        imageView2.setMaskOrientation(XCLoadingImageView.MaskOrientation.LeftToRight);        imageView2.setProgress(50);    }}

六、源码下载

源码下载http://download.csdn.net/detail/jczmdeveloper/9344987

GitHub地址https://github.com/jczmdeveloper/XCLoadingImageView

真题园网http://www.zhentiyuan.com

时间: 2024-10-25 03:56:12

Android 自定义View修炼-自定义加载进度动画LoadingImageView的相关文章

Android 自定义View修炼-自定义弹幕效果View

一.概述 现在有个很流行的效果就是弹幕效果,满屏幕的文字从右到左飘来飘去.看的眼花缭乱,看起来还蛮cool的 现在就是来实现这一的一个效果,大部分的都是从右向左移动漂移,本文的效果中也支持从左向右的漂移移动 效果. 二.效果图 废话不说,先来看看效果图吧~~ 三.实现原理方案 1.自定义ViewGroup-XCDanmuView,继承RelativeLayout来实现,当然也可以继承其他三大布局类哈 2.初始化若干个TextView(弹幕的item View,这里以TextView 为例,当然也

pace.js和NProgress.js两个加载进度插件的一点小总结

这两个插件都是关于加载进度动画的,应该说各有特点吧,最起码对我来说是各有优势的.今天一天就捣鼓了加载进度动画,也研究了大量的(也就这两个)加载进度动画,也算对加载进度动画有了一个初步的了解了吧. NProgress.js NProgress是基于jquery的,且版本要 >1.8 API: NProgress.start() — 启动进度条 NProgress.set(0.4) — 将进度设置到具体的百分比位置 NProgress.inc() — 少量增加进度 NProgress.done() 

刚入前端整合的一个手机端页面适配+预加载+获取资源加载进度等的一个小模板

刚入前端不久,之前主要学的是pc端的布局,到公司之后负责的主要是移动段页面,刚开始时为了使页面适应移动端不同的屏幕大小采用的是百分比加媒体查询的方式,做完一个项目之后,感觉非常不好,虽然最后也基本使页面做到了适配.所以做完这个项目之后,我就在网上查找各种屏幕适配的方案,最终找到了一个通过js控制使页面整体缩放的方案,还有一个就是通过js实时检测屏幕大改变html根字体大小的rem布局方案.目前我在使用的是缩放的方案.整体代码基本上是整合的是大牛们分享的一些实用代码,如有什么bug欢迎提出,共同进

【Web前沿技术】纯 CSS3 打造的10个精美加载进度条动画

之前向大家介绍8款优秀的 jQuery 加载动画和进度条插件,今天这篇文章向大家推荐10个纯 CSS3 代码实现精美加载进度条动画效果的方案.加载动画和进度条在网站和 Web 应用中的使用非常流行,特别是在使用 Ajax 技术加载内容的应用场景中,使用时尚的加载动画和进度条告诉用户内容正在加载中是一种非常友好的方式. 您可能感兴趣的相关文章 20个非常绚丽的 CSS3 特性应用演示 23个纯 CSS3 打造的精美LOGO图案 35个让人惊讶的 CSS3 动画效果演示 推荐12个漂亮的 CSS3

自定义View基础之——图片加载进度条

学会了Paint,Canvas的基本用法之后,我们就可以动手开始实践了,先写个简单的图片加载进度条看看. 按照惯例,先看效果图,再决定要不要往下看: 既然看到这里了,应该是想了解这个图片加载进度条了,我们先看具体用法,再看自定义View的实现: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.co

我的Android进阶之旅------&gt;Android自定义View实现带数字的进度条(NumberProgressBar)

今天在Github上面看到一个来自于 daimajia所写的关于Android自定义View实现带数字的进度条(NumberProgressBar)的精彩案例,在这里分享给大家一起来学习学习!同时感谢daimajia的开源奉献! 第一步.效果展示 图1.蓝色的进度条 图2.红色的进度条 图3.多条颜色不同的进度条 图4.多条颜色不同的进度条 版权声明:本文为[欧阳鹏]原创文章,欢迎转载,转载请注明出处! [http://blog.csdn.net/ouyang_peng/article/deta

Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)

转载请注明地址:http://blog.csdn.net/xiaanming/article/details/10298163 很多的时候,系统自带的View满足不了我们功能的需求,那么我们就需要自己来自定义一个能满足我们需求的View,自定义View我们需要先继承View,添加类的构造方法,重写父类View的一些方法,例如onDraw,为了我们自定义的View在一个项目中能够重用,有时候我们需要自定义其属性,举个很简单的例子,我在项目中的多个界面使用我自定义的View,每个界面该自定义View

使用谷歌提供的SwipeRefreshLayout下拉控件,并自定义实现下拉加载的功能

package com.loaderman.swiperefreshdemo; import android.os.Bundle; import android.os.Handler; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.app.AppCompatActivity; import android.view.Gravity; import android.view.View;

Dialog详解(包括进度条、PopupWindow、自定义view、自定义样式的对话框)

Android中提供了多种对话框,在实际应用中我们可能会需要修改这些已有的对话框.本实例就是从实际出发,展现了andorid中大部分对话框,代码中用了一个对话框管理类来做封装,其中还定义了对话框的动画.自定义样式等等. 主布局文件(全是button) <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.co