FruitLoadView 一个自定义view可用来做加载view
2016-07-22 12:18
423 查看
闲暇时自己做得一个自定义view,后续如果还有时间的话再去增强功能。
Github地址:https://github.com/X-FAN/FruitLoadView 欢迎star
效果图
博客上的图片文件不能太大,github效果图要清晰些,大家将就下
2016.8.5:
新增fruitDrawableArray属性,可以在跳动中变换
源码还是比较简单的
Github地址:https://github.com/X-FAN/FruitLoadView 欢迎star
效果图
博客上的图片文件不能太大,github效果图要清晰些,大家将就下
2016.8.5:
新增fruitDrawableArray属性,可以在跳动中变换
源码还是比较简单的
public class FruitLoadView extends View { private final String TAG = "Fruit"; private int mWidth; private int mHeight; private int mOvalW; private int mOvalH; private int mStartHeight; private int mFruitHeight; private int mFruitWidth; private int mIndex = 1; private int mLength; private boolean mIsDraw = false; private boolean mIsMutliMode = false; private boolean mIsHasChanged = false;//是否已经变换过在达到最高前 private float mMinScale; private float mAnimatedValue = 1.0f; private List<Drawable> mFruitDrawables; private Drawable mFruitDrawable; private ValueAnimator mScaleLargerAnimator; private Paint mPaint; private RectF mOv 4000 alRectF; public FruitLoadView(Context context) { this(context, null); } public FruitLoadView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public FruitLoadView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context, attrs); } private void init(Context context, AttributeSet attrs) { if (attrs == null) { return; } TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FruitLoadView); handleMultiDrawable(a); if (!mIsMutliMode) { mFruitDrawable = a.getDrawable(R.styleable.FruitLoadView_fruitDrawable); if (mFruitDrawable == null) { throw new NullPointerException("fruit drawable is null"); } } int shadowColor = a.getColor(R.styleable.FruitLoadView_shadowColor, 0xFFE6E6E6); int animatorDuration = a.getInt(R.styleable.FruitLoadView_animatorDuration, 1000); int maxHeight = a.getDimensionPixelSize(R.styleable.FruitLoadView_maxHeight, 100); int fruitHeight = a.getDimensionPixelSize(R.styleable.FruitLoadView_fruitHeight, -1); int fruitWidth = a.getDimensionPixelSize(R.styleable.FruitLoadView_fruitWidth, -1); if (fruitHeight > 0) { mFruitHeight = fruitHeight; } else { mFruitHeight = mFruitDrawable.getIntrinsicHeight(); } if (fruitWidth > 0) { mFruitWidth = fruitWidth; } else { mFruitWidth = mFruitDrawable.getIntrinsicWidth(); } mOvalW = mFruitWidth / 2; mOvalH = (int) (mFruitHeight * 0.5) / 2; mStartHeight = mFruitHeight + maxHeight; mMinScale = (float) mFruitHeight / (float) mStartHeight; mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setColor(shadowColor); mOvalRectF = new RectF(); initAnimator(animatorDuration); a.recycle(); } /** * 处理多个drawable的情况 * * @param a */ private void handleMultiDrawable(TypedArray a) { int resId = a.getResourceId(R.styleable.FruitLoadView_fruitDrawableArray, -1); if (resId != -1) { Resources resources = getResources(); TypedArray typedArray = resources.obtainTypedArray(resId); mFruitDrawables = new ArrayList<>(); for (int i = 0; i < typedArray.length(); i++) { Drawable drawable = typedArray.getDrawable(i); mFruitDrawables.add(drawable); } if (!mFruitDrawables.isEmpty()) { mIsMutliMode = true; mFruitDrawable = mFruitDrawables.get(0); mLength = mFruitDrawables.size(); } typedArray.recycle(); } } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mWidth = w; mHeight = h; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (mIsDraw) { canvas.translate(mWidth / 2, mHeight / 2);// 将画布坐标原点移动到中心位置 canvas.save(); canvas.drawOval(mOvalRectF, mPaint); mFruitDrawable.setBounds(-mOvalW, (int) (-mStartHeight * mAnimatedValue), mOvalW, (int) (-(mStartHeight * mAnimatedValue - mFruitHeight))); mFruitDrawable.draw(canvas); canvas.restore(); } } private void initAnimator(long duration) { mScaleLargerAnimator = ValueAnimator.ofFloat(1.0f, mMinScale, 1.0f).setDuration(duration); mScaleLargerAnimator.setInterpolator(new DecelerateInterpolator()); mScaleLargerAnimator.setRepeatCount(ValueAnimator.INFINITE); mScaleLargerAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mAnimatedValue = (float) animation.getAnimatedValue(); if (mAnimatedValue > 0.9f) {//认为达到最高点 mIsHasChanged = false; } mOvalRectF.set(-mOvalW * mAnimatedValue, -mOvalH * mAnimatedValue, mOvalW * mAnimatedValue, mOvalH * mAnimatedValue); changeDrawable(); invalidate(); } }); mScaleLargerAnimator.start(); } /** * 变更需要绘制的drawable */ private void changeDrawable() { //差值小于0.05f即认为在最低点 if (mIsMutliMode && !mIsHasChanged && (mAnimatedValue - mMinScale) < 0.05f) { mFruitDrawable = mFruitDrawables.get(mIndex); if (mIndex < mLength - 1) { mIndex++; } else { mIndex = 0; } mIsHasChanged = true; } } /** * 是否正在展示 * * @return */ public boolean isShowing() { return mIsDraw; } /** * 展示 */ public void showLoading() { mIsDraw = true; mScaleLargerAnimator.start(); } /** * 消失 */ public void hideLoading() { mIsDraw = false; mScaleLargerAnimator.cancel(); mScaleLargerAnimator.end(); } }
相关文章推荐
- JAVA生成短8位UUID(未测试)
- 百度ueditor图片上传提示“上传失败,请重试”解决办法
- java学习之学习GUI建议
- 页面编辑器传值到C#后台检测到有潜在危险的 Request.Form 值
- F - True Liars POJ 1417(并查集)(DFS)
- Wiggle Subsequence
- LeetCode - 304. Range Sum Query 2D - Immutable
- LeetCode - 225. Implement Stack Using Queues
- MySQL实现序列(Sequence)效果
- UESTC 94 - Bracket Sequence(线段树+区间合并)
- [Sencha ExtJS6 Modern] 改进bug: field控件框在reset之后,控件框清除了,但是getValue()还能获取旧值,而且setValue(旧值)没反应
- android studio build工程时报错agpbi{}
- GUI应用程序架构的十年变迁:MVC,MVP,MVVM,Unidirectional,Clean
- UITableViewCell 复用笔记(一)结构设计
- 自定义系统导航栏UINavigationBarController。
- 树形DP——Rebuilding Roads ( POJ 1947 )
- java.lang.IllegalStateException: Required view 'text1' with ID 2131492943 for field 'mText' was not found. If this view is optional add '@Nullable' annotation
- Arduino模拟空调遥控器
- 阿里巴巴Druid数据源,史上最强的数据源,没有之一
- iOS-UIScrollView简单的自动滚动效果