Android从零开始(第五篇)手把手教撸一个仿饿了么LoadingView(一)

前言

过年放假前最后一天班,就想着做个简单又有趣的小东西。于是决定来写个自定义的LoadingView作为这个App框架的加载效果吧。

走过路过点歌Start O(∩_∩)O
Github项目地址

这篇文章叫你如何搭建手写LoadingView,看完这篇文章你能学会:

  1. 属性动画使用
  2. 自定义View

--------------------------------关门,上分割线------------------------------------------------
先看看效果:
在这里插入图片描述
有点像饿了么那种风格。
最重要的,在看到这个效果之前脑中想到的实现思路:

1.创建item_loading_view.xml布局,把样式先写出来
2.自定义View,加载这个自定义布局
3.自定义View内做动画处理

1.布局:item_loading_view.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:padding="24dp"
    android:layout_height="148dp">

    <ImageView
        android:id="@+id/iv_loading"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_above="@+id/tv_loading"
        android:src="@drawable/ic_favorites" />
    <TextView
        android:id="@+id/tv_loading"
        android:layout_width="wrap_content"
        android:text="加载中..."
        android:layout_marginTop="12dp"
        android:layout_centerHorizontal="true"
        android:layout_alignParentBottom="true"
        android:layout_height="wrap_content" />

</RelativeLayout>

2.自定义View

public class LoadingView extends FrameLayout {

    public LoadingView(Context context) {
        this(context,null);
    }

    public LoadingView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // 加载布局
        LayoutInflater.from(mContext).inflate(R.layout.item_loading_view, this);
    }

这个时候在Activity的布局中引用的话,能看到这个loadingView的静态效果了。最后最关键的一步
3.动画效果实现:
这里面涉及到两个动画效果,一个是那个爱心上下跳动,以及底下一个阴影缩放
爱心上下跳动效果:

 private void logic() {
        ValueAnimator animator = ValueAnimator.ofInt(0,mJumpHeightPx,0);
        animator.setDuration(800);
        animator.setRepeatMode(ValueAnimator.RESTART);
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.setInterpolator(new AccelerateDecelerateInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int value = (int) animation.getAnimatedValue();
                mIv.setTranslationY(-value);
                // 为了画shadow
                mMovePercent = value / 100f;
                postInvalidate();
            }
        });
        animator.start();
    }

LoaingView构造函数中调用该方法(详细见githun项目源码)
实现思路:利用属性动画移动
关于属性动画作用的原理可以去百度几篇文章,一句话概括就是,属性动画提供的是:使用某种变化规则去得到一个不断变化值,然后自己利用这个值去设置控件的属性以达到动画的效果。

shadow缩放效果:

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 阴影宽高的一半   最大不超过16 / 8
        float shadowHalfWidth = Math.max(16f,(mIvRight - mIvLeft) / 2 );
        float shadowHalfHeight = Math.max(8f,(mIvBottom - mIvTop) / 2 );
        // 阴影区域中线位置(决定阴影所在位置) yCenter:垂直中线的纵坐标 xCenter:水平中线的横坐标
        float yCenter = mIvLeft + shadowHalfWidth;
        float xCenter = mIvTop + shadowHalfHeight * 2;
        // 缩放的变化量(决定阴影变化大小)
        float horizontalDiff = Math.max(2,(1f - mMovePercent) * shadowHalfWidth * mShadowFlatX);
        float verticalDiff = Math.max(2,(1f - mMovePercent) * shadowHalfHeight * mShadowFlatY);
        Log.d("bigname", "onDraw: " + yCenter + "-----" + xCenter + "------" + horizontalDiff + "--------" + verticalDiff + "-------" + mMovePercent);
        mShadowRectF.set(
                yCenter - horizontalDiff,
                xCenter - verticalDiff,
                yCenter + horizontalDiff,
                xCenter + verticalDiff
        );
        canvas.drawOval(mShadowRectF, mShadowPaint);
    }

shadow利用画布去实现:
首先在使用属性动画的时候将变化的值赋给全局变量mMovePercent;并且变化的时候调用postInvalidate()重绘,这样的话在onDraw()方法中接口和mMovePercent就能知道当前动画进行的进度。依此来控制shadow缩放。

这个自定义LoadingView效果就已经实现了,接下来会对这个控件做些优化,增加更炫的动画效果,然后做好封装。

源码在上面的github链接

敬请期待—

MySQL数据库从入门实战课

12-31
限时福利1:购课进答疑群专享柳峰(刘运强)老师答疑服务。 限时福利2:购课后添加学习助手(微信号:csdn590),按消息提示即可领取编程大礼包! 注意:原价129的课程,最后2天限时秒杀仅需49元!! 为什么说每一个程序员都应该学习MySQL? 根据《2019-2020年中国开发者调查报告》显示,超83%的开发者都在使用MySQL数据库。 使用量大同时,掌握MySQL早已是运维、DBA的必备技能,甚至部分IT开发岗位也要求对数据库使用和原理有深入的了解和掌握。 学习编程,你可能会犹豫选择 C++ 还是 Java;入门数据科学,你可能会纠结于选择 Python 还是 R;但无论如何, MySQL 都是 IT 从业人员不可或缺的技能! 【课程设计】 在本课程中,刘运强老师会结合自己十多年来对MySQL的心得体会,通过课程给你分享一条高效的MySQL入门捷径,让学员少走弯路,彻底搞懂MySQL。 本课程包含3大模块:  一、基础篇: 主要以最新的MySQL8.0安装为例帮助学员解决安装与配置MySQL的问题,并对MySQL8.0的新特性做一定介绍,为后续的课程展开做好环境部署。 二、SQL语言篇: 本篇主要讲解SQL语言的四大部分数据查询语言DQL,数据操纵语言DML,数据定义语言DDL,数据控制语言DCL,学会熟练对库表进行增删改查等必备技能。 三、MySQL进阶篇: 本篇可以帮助学员更加高效的管理线上的MySQL数据库;具备MySQL的日常运维能力,语句调优、备份恢复等思路。  
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值