58同城加载动画
来源:互联网 发布:期权 内在价值 知乎 编辑:程序博客网 时间:2024/05/16 19:39
一、效果先行
二、功能实现
1.布局分析
可以看到上图可分为三部分,最上面是弹跳的几何形状图形,中间是阴影指示器,最下面是文字,所以布局用LinearLayout,最上面暂且放ImageView,中间放ImageView , 最下面放置文字
1.ui_loding_view.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_horizontal" android:orientation="vertical"> <ImageView android:id="@+id/shapeLoadingView" android:layout_width="24dp" android:layout_height="24dp" android:layout_centerHorizontal="true" android:layout_marginTop="4dp" /> <ImageView android:id="@+id/indication" android:layout_width="23dp" android:layout_height="3dp" android:layout_centerHorizontal="true" android:layout_marginTop="82dp" android:src="@drawable/shadow" /> <TextView android:id="@+id/promptTV" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/indication" android:layout_centerHorizontal="true" android:layout_marginTop="18dp" android:textColor="#757575" android:text="玩命加载中..." android:textSize="14sp" /></LinearLayout>
2.LoadingView 继承自 LinearLayout
public class LoadingView extends LinearLayout{ private ImageView mShapeLodingView,mIndicationView; private Context mContext; 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); this.mContext = context; initLayout(); } private void initLayout() { View.inflate(mContext, R.layout.load_view,this); mShapeLodingView = (ShapeLoadingView) findViewById(R.id.shapeLoadingView); mIndicationView = (ImageView) findViewById(R.id.indication); }
2.动画分析
这里可以看做两个部分的动画,一个是上面几何图形的下落上抛动画,一个是中间阴影指示器放大缩小的动画,如果能这样组合就算实现了:当几何图形下落时配合阴影放大,当几何图形上抛时配合中间阴影缩小。这里需要用到ObjectAnimator属性动画http://blog.csdn.net/lmj623565791/article/details/38067475
3.动画实现
//初始化下落动画 private void initFreeFallAnimation() { // 下落动画集合 mFreeFallAnimatiorSet = new AnimatorSet(); // 几何图形的垂直位移动画 ObjectAnimator freeFallTranslationAnimator = ObjectAnimator.ofFloat( mShapeLodingView, "translationY", 0, mTranslationYDistance); // 定义动画的变化率。 freeFallTranslationAnimator.setInterpolator(new AccelerateInterpolator(factor)); // 中间阴影缩小动画 ObjectAnimator scaleIndication = ObjectAnimator.ofFloat(mIndicationView, "scaleX", 1, 0.2f); mFreeFallAnimatiorSet.setDuration(ANIMATION_DURATION); mFreeFallAnimatiorSet.playTogether(freeFallTranslationAnimator, scaleIndication); mFreeFallAnimatiorSet.addListener(new AnimatorListenerAdapter() { //设置动画监听器,监听该动画的开始、停止、取消、结束等状态,我们往往会用AnimtorListener适配器类来只实现我们需要的方法 @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); // 下落动画结束,改变形状,然后执行上抛动画 upThrow(); mShapeLodingView.changeShape(); } }); }
上抛动画其实和下落动画差不多,只要在下落动画执行完之后启动上抛动画即可,但是我们需要在下落动画结束完后改变形状,最直接的方式便是改变几何图像ImageView的背景资源即可,但是个人认为这样不是太好,所以需要自定义几何形状ShapeLoadingView,然后提供一个changeShape()的方法,里面调用invalidate(),在onDraw(Canvas canvas)中画对应的几何形状
4.自定义几何view
public class ShapeLoadingView extends View{ // 圆 ,三角 ,正方形 的画笔 private Paint mPaint; // 宽度和高度 private int mHeigth,mWidth; // 当前是什么形状 private Shape mCureentShape; public ShapeLoadingView(Context context) { this(context, null); } public ShapeLoadingView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ShapeLoadingView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initData(); } private void initData() { mPaint = new Paint(); mPaint.setAntiAlias(true); mCureentShape = Shape.SHAPE_CIRCLE; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mHeigth = getMeasuredHeight(); mWidth = getMeasuredWidth(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); switch (mCureentShape){ case SHAPE_CIRCLE: drawCircle(canvas); break; case SHAPE_TRIANGLE: drawTriangle(canvas); break; case SHAPE_RECT: drawRect(canvas); break; } } /** * 画正方形 */ private void drawRect(Canvas canvas) { mPaint.setColor(getResources().getColor(R.color.rect)); canvas.drawRect(0, 0, mWidth, mHeigth, mPaint); } /** * 画三角形 */ private void drawTriangle(Canvas canvas) { mPaint.setColor(getResources().getColor(R.color.triangle)); Path path = new Path(); path.moveTo(mWidth / 2, 0); path.lineTo(0, mHeigth); path.lineTo(mWidth, mHeigth); path.close(); canvas.drawPath(path, mPaint); } /** * 画圆形 */ private void drawCircle(Canvas canvas) { mPaint.setColor(getResources().getColor(R.color.circle)); canvas.drawCircle(mWidth / 2, mHeigth / 2, mWidth / 2, mPaint); } /** * 改变形状 */ public void changeShape() { switch (mCureentShape){ case SHAPE_CIRCLE: mCureentShape = Shape.SHAPE_RECT; break; case SHAPE_RECT: mCureentShape = Shape.SHAPE_TRIANGLE; break; case SHAPE_TRIANGLE: mCureentShape = Shape.SHAPE_CIRCLE; break; } // 重新绘制 invalidate(); } public enum Shape{ // 三角 SHAPE_TRIANGLE, // 四边形 SHAPE_RECT, // 圆形 SHAPE_CIRCLE }}
4.旋转动画
最后就剩两个旋转的动画了,我们旋转的动画以及角度问题我们直接从自定义ShapeLoadingView 中获取,提供一个getUpThrowRoteAnimation()方法
/** * 在ShapeLoadingView的构造方法中初始化旋转动画即可 */ private void initRoteAnimation() { mRectRoteAnimation = ObjectAnimator.ofFloat(this, "rotation", 0, -120); mDefaultRoteAnimation = ObjectAnimator.ofFloat(this, "rotation", 0, 180); } /** * 得到当前正在上抛时应该旋转的动画 */ public ObjectAnimator getUpThrowRoteAnimation() { switch (mCureentShape){ case SHAPE_RECT: return mRectRoteAnimation; default: return mDefaultRoteAnimation; } }
给上抛动画设置动画监听,在其onAnimationStart()中执行旋转动画
mUpThrowAnimatiorSet.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); //动画结束,下落 freeFall(); } @Override public void onAnimationStart(Animator animation) { super.onAnimationStart(animation); // 动画开始,和旋转动画一起执行 startShapeRoteAnimator(); } /** * 执行旋转动画 */ private void startShapeRoteAnimator() { ObjectAnimator roteAnimation = mShapeLodingView.getUpThrowRoteAnimation(); roteAnimation.setDuration(ANIMATION_DURATION); roteAnimation.setInterpolator(new DecelerateInterpolator(factor)); roteAnimation.start(); } });
源码下载:http://download.csdn.net/detail/z240336124/9353335
- 58同城加载动画
- 仿58同城加载动画
- 仿58同城加载动画
- 58同城加载动画的实现( Android属性动画)
- Iwfu-仿58同城加载页的自定义加载动画
- Android加载中动画,仿58同城,美团效果
- 58同城引导页动画
- ios loading视图动画(模仿58同城)
- 学习自定义View(二)仿58同城加载
- 58同城
- 高仿58加载动画
- 加载动画
- 加载动画
- 加载动画
- (HttpClient技术)(58同城系列)58同城登录
- (HttpClient技术)(58同城系列)58同城发帖
- 仿58同城站内搜索
- 仿58同城站内搜索
- 浅析C++中虚函数的调用及对象的内部布局http://blog.csdn.net/starlee/article/details/2089358
- 软件测试与软件质量-什么是软件质量
- C#_HashTable和SortedList的使用方法
- objective-c视频教程
- POJ 3279.Fliptile
- 58同城加载动画
- Java基础——Java重点基础之面向对象思想
- js模块化之模块依赖处理
- objective-c学习方法总结
- 软件测试与软件质量-软件测试与质量保证的区别
- Android 数据存储(一)文件存储
- 117 php __autoload 和 spl_autoload_register
- ROS学习笔记二:ubuntu软件源配置(二)
- java web遇到的各种问题汇总