仿易讯客户端loading效果

下面来实现一个loading效果。具体效果如下:

首先对这个效果进行拆分,它由以下部分组成:

  • 1 一个”闪电”样式的图案;
  • 2 “闪电”图案背后是一个圆角矩形;
  • 3 “闪电”图案上面有一层颜色不断”飘过”

拆分完效果后,思考下如何实现。下面是我的思考过程。

  • 1 android sdk并没有提供这样的控件,很显然是需要自定义控件;
  • 2 很显然是一个View而不是ViewGroup,所以可以继承View;
  • 3 重点是onDraw的逻辑;
  • 4 怎样绘制”闪电”的图案?可以通过Path绘制;
  • 5 怎样绘制”闪电”背后的圆角矩形?canvas.drawRoundRect;
  • 6 怎样实现”闪电”的动效?仔细观察,发现上方那层颜色的运动规律是从0~闪电高度不断扩大,到达闪电高度的时候,高度不断减小直到0。所以可以通过控制高度的方式实现。只要有两个变量scanTop/scanBottom记录绘制的上下界限即可,然后控制scanTop/scanBottom进行变化即可,怎样控制变化很显然可以通过post/postDelayed实现。另外一个难点是如何绘制部分”闪电”?思索一番,可以通过canvas.clipRect的方式控制绘制区域,这样间接实现了我们需要的效果;
  • 7 核心逻辑实现之后,需要考虑到应该让这个自定义控件支持wrap_content.这必然需要重写onMeasure,并考虑到父容器的MeasureSpec(view的默认实现下wrap_content和match_parent效果一样);
  • 8 需要让这个控件支持padding。所以得在measure和draw的过程中充分考虑到padding这个因素;
  • 9 当view被detach的时候,需要remove掉动画;
  • 10 应该提供几个默认大小,比如small/midium/large,这可以通过自定义属性实现。

大致思考完之后,可以写代码了。

首先是measure过程:

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        //需要计算自己实际需要的宽高
        //需要把padding考虑进来
        //需要考虑父容器的测量规则

        int width,height;

        width = (int)mViewMinWidth+getPaddingLeft()+getPaddingRight();
        height = (int)mViewMinHeight+getPaddingTop()+getPaddingBottom();

        setMeasuredDimension(getMeasuredSize(widthMeasureSpec, width), getMeasuredSize(heightMeasureSpec, height));
    }

通过getMeasuredSize计算考虑父容器限制后的实际大小:

private int getMeasuredSize(int measureSpec,int desiredSize){

        int result;

        int mode = MeasureSpec.getMode(measureSpec);
        int size = MeasureSpec.getSize(measureSpec);

        switch (mode){
            case MeasureSpec.EXACTLY:
                result = size;
                break;
            default:
                result = desiredSize;
                if(mode == MeasureSpec.AT_MOST)
                    result = Math.min(result,size);
                break;
        }

        return result;

    }

然后是draw的过程:


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        mPaint.setColor(mViewBackground);
        //如果xml中设置layout_width/layout_height大于默认宽高,那么居中(不允许小于默认宽高)
        if(getWidth()-getPaddingLeft()-getPaddingRight() > (int)mViewMinWidth || getHeight()-getPaddingTop()-getPaddingBottom() > (int)mViewMinHeight){
           canvas.translate((getWidth()-mViewMinWidth)/2.0f,(getHeight()-mViewMinHeight)/2.0f);
        }
        //画圆角矩形
        canvas.drawRoundRect(mBounds, dp2px(5), dp2px(5), mPaint);
        //平移到圆角矩形中心点,画闪电
        canvas.translate((mViewMinWidth - mDefaultWidth) / 2.0f, (mViewMinHeight - mDefaultHeight) / 2.0f);
        mPaint.setColor(mBackgroundColor);

        canvas.drawPath(mThunderPath, mPaint);
        mPaint.setColor(mCoverColor);
        //通过clicpRect的方式控制可绘制区域(在外界看来好像有闪动的动画效果)
        canvas.clipRect(getPaddingLeft(), mScanTop + getPaddingTop(), mDefaultWidth + getPaddingLeft(), mScanBottom + getPaddingTop());
        canvas.drawPath(mThunderPath, mPaint);
    }

mScanTop/mScanBottom变量可以通过post()进行改变:

class AnimRunnable implements Runnable{
        @Override
        public void run() {
            if (!flag) {
                mScanBottom += mGap;
                if (mScanBottom >= mDefaultHeight) {
                    mScanBottom = (int) mDefaultHeight;
                    flag = true;
                }
                postInvalidate();
                post(this);
            } else {
                mScanTop += mGap;
                if (mScanTop >= mDefaultHeight) {
                    mScanTop = mScanBottom = 0;
                    flag = false;
                    postInvalidate();
                    postDelayed(this, 700);
                } else {
                    postInvalidate();
                    post(this);
                }
            }
        }
    }
private void startAnim() {
        mRunnable = new AnimRunnable();
        post(mRunnable);
    }

核心代码就这么多。

完整代码在这里:https://github.com/Rowandjj/ThunderLoadingView

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-26 16:00:26

仿易讯客户端loading效果的相关文章

仿易讯clientloading效果

以下来实现一个loading效果.详细效果例如以下: 首先对这个效果进行拆分,它由以下部分组成: 1 一个"闪电"样式的图案. 2 "闪电"图案背后是一个圆角矩形; 3 "闪电"图案上面有一层颜色不断"飘过" 拆分完效果后.思考下如何实现.以下是我的思考过程. 1 android sdk并没有提供这种控件,非常显然是须要自己定义控件. 2 非常显然是一个View而不是ViewGroup.所以能够继承View; 3 重点是onD

Canvas 仿百度贴吧客户端 loading 小球

前言 几天前在简书上看到在一篇文章<Android仿百度贴吧客户端Loading小球>,看了一下作者,他写了两个好玩的 demo,效果图如下: 今天趁着周末有空,用 H5 的 Canvas 仿了一下.这篇文章只实现第一个效果图.这是我实现的效果: 实现原理 实现原理是参考简书的那篇文章,这里不再复述.现在我们来一步一步实现这样的效果. 第零步:画一个圆 源码如下: <!DOCTYPE html> <html> <head> <meta charset=

完美拖拽 &amp;&amp;仿腾讯微博效果&amp;&amp; 自定义多级右键菜单

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-

Js仿腾讯微博效果,无刷新删除微博

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-

仿易信UI设计

  大家好,这是前段时间仿易信Android客户端UI做的一个小程序,资源就是易信客户端里面找的,作为练手学习之用,希望大家喜欢! 首先是第一次使用的导航页面,效果图: 主要是处理当手左右滑动时小圆点也跟随切换的问题,这个页面的逻辑代码如下: public class WelcomeActivity extends Activity{ ViewPager mPager; MyAdapter myAdapter; List<View> views=new ArrayList<View>

【Android UI设计与开发】7.底部菜单栏(四)PopupWindow 实现显示仿腾讯新闻菜单

前一篇文章中有用到 PopupWindow 来实现弹窗的功能.简单介绍以下吧. 官方文档是这样解释的:这就是一个弹出窗口,可以用来显示一个任意视图.出现的弹出窗口是一个浮动容器的当前活动. 1.首先来个简单的栗子,效果如下: 只有两个布局文件,一个是弹窗布局(只有一张图片),一个是主界面布局(只有一个按钮). 然后在主界面代码中实例 PopupWindow ,指定弹出的界面,在按钮点击事件中显示或隐藏弹窗就可以了,代码如下: package com.yanis.demo; import andr

Android 使用ContentProvider扫描手机中的图片,仿微信显示本地图片效果

首先我们先看第一个界面吧,使用将手机中的图片扫描出来,然后根据图片的所在的文件夹将其分类出来,并显示所在文件夹里面的一张图片和文件夹中图片个数,我们根据界面元素(文件夹名, 文件夹图片个数,文件夹中的一张图片)使用一个实体对象ImageBean来封装这三个属性 package com.example.imagescan; /** * GridView的每个item的数据对象 * * @author len * */ public class ImageBean{ /** * 文件夹的第一张图片路

Jquery实现仿腾讯微薄的广播发表

前言: 由于这几天在学习Jquery的一些知识,比以前的感觉就是Jquery太强大了,很多很简单的功能以前在JavaScript要写几十行的代码而在Jquery中只用几行代码就搞定了,所以我决定好好学习学习Jquery,支持我吧,呵呵,这几天的学习Jquey使我感觉到其实Jquery的使用并不是很难,就我感觉Jquery只要把选择器学的差不多,其他的基本都可以迎刃而解,多了解一些方法,事件等等.所以我在这里实现了一个Jquery实现仿腾讯微薄的广播发表. 1. 首先新建HTML页面和介绍我要实现

高仿淘宝客户端

高仿淘宝客户端 仿淘宝安卓客户端的demo源码,主要实现了:商品的基本展示.宝贝详情,图片展示的放大缩小功能.界面之间切换的动画.购物车多项删除.弹窗的动画效果.首页广告的轮播效果.获得本机具有传感器的列表.listView的上拉刷新,下拉加载功能.二维码扫描.刮刮乐等功能和效果. 下载地址:http://www.devstore.cn/code/info/925.html 运行截图: