zoukankan      html  css  js  c++  java
  • Android 用属性动画自定义view的渐变背景

    自定义view渐变背景,同时监听手势自动生成小圆球。

    宿主Activity如下:

    package com.edaixi.tempbak;
    
    import java.util.ArrayList;
    import android.animation.Animator;
    import android.animation.AnimatorListenerAdapter;
    import android.animation.AnimatorSet;
    import android.animation.ArgbEvaluator;
    import android.animation.ObjectAnimator;
    import android.animation.ValueAnimator;
    import android.annotation.SuppressLint;
    import android.app.Activity;
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.graphics.RadialGradient;
    import android.graphics.Shader;
    import android.graphics.drawable.ShapeDrawable;
    import android.graphics.drawable.shapes.OvalShape;
    import android.os.Bundle;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.Window;
    import android.view.animation.AccelerateInterpolator;
    import android.view.animation.DecelerateInterpolator;
    import android.widget.LinearLayout;
    
    @SuppressLint("NewApi")
    public class MainActivity extends Activity {
    
    	/** Called when the activity is first created. */
    	@Override
    	public void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		requestWindowFeature(Window.FEATURE_NO_TITLE);
    		setContentView(R.layout.activity_main);
    		LinearLayout container = (LinearLayout) findViewById(R.id.container);
    		container.addView(new MyAnimationView(this));
    	}
    
    	public class MyAnimationView extends View {
    
    		private static final int RED = 0xffFF8080;
    		private static final int BLUE = 0xff8080FF;
    		private static final int CYAN = 0xff80ffff;
    		private static final int GREEN = 0xff80ff80;
    
    		public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();
    		AnimatorSet animation = null;
    
    		public MyAnimationView(Context context) {
    			super(context);
    			/**************************************************************************************************
    			 * 
    			 * 设置自定义view的背景,是一个渐变的过程,用ValueAnimator实现,ValueAnimator是Property
    			 * Animation系统 的核心类,它包含了配置Property Animation属性的大部分方法,那要实现一个Property
    			 * Animation,都需要直接 或间接使用ValueAnimator类,使用ValueAnimator的步骤如下:
    			 * 1.调用ValueAnimation类中的ofInt(int...values)、ofFloat(String
    			 * propertyName,float...values)等静态方
    			 * 法实例化ValueAnimator对象,并设置目标属性的属性名、初始值或结束值等值;
    			 * 2.调用addUpdateListener(AnimatorUpdateListener
    			 * mListener)方法为ValueAnimator对象设置属性变化的监听器
    			 * 3.创建自定义的Interpolator,调用setInterpolator(TimeInterpolator
    			 * value)为ValueAniamtor设置自定义的 Interpolator;(可选,不设置默认为缺省值)
    			 * 4.创建自定义的TypeEvaluator,调用setEvaluator(TypeEvaluator
    			 * value)为ValueAnimator设置自定义的 TypeEvaluator;(可选,不设置默认为缺省值)
    			 * 5.在AnimatorUpdateListener 中的实现方法为目标对象的属性设置计算好的属性值。
    			 * 6.设置动画的持续时间、是否重复及重复次数等属性; 7.为ValueAnimator设置目标对象并开始执行动画。
    			 * 
    			 * *****************************************************************
    			 */
    			ValueAnimator colorAnim = ObjectAnimator.ofInt(this,
    					"backgroundColor", RED, BLUE);
    			colorAnim.setDuration(3000);
    			colorAnim.setEvaluator(new ArgbEvaluator());
    			colorAnim.setRepeatCount(ValueAnimator.INFINITE);
    			colorAnim.setRepeatMode(ValueAnimator.REVERSE);
    			colorAnim.start();
    		}
    
    		@SuppressLint("NewApi")
    		@Override
    		public boolean onTouchEvent(MotionEvent event) {
    			if (event.getAction() != MotionEvent.ACTION_DOWN
    					&& event.getAction() != MotionEvent.ACTION_MOVE) {
    				return false;
    			}
    			ShapeHolder newBall = addBall(event.getX(), event.getY());
    
    			/** Bouncing animation with squash and stretch **/
    			float startY = newBall.getY();
    			float endY = getHeight() - 50f;
    			float h = (float) getHeight();
    			float eventY = event.getY();
    			int duration = (int) (500 * ((h - eventY) / h));
    			ValueAnimator bounceAnim = ObjectAnimator.ofFloat(newBall, "y",
    					startY, endY);
    			bounceAnim.setDuration(duration);
    			bounceAnim.setInterpolator(new AccelerateInterpolator());
    			ValueAnimator squashAnim1 = ObjectAnimator.ofFloat(newBall, "x",
    					newBall.getX(), newBall.getX() - 25f);
    			squashAnim1.setDuration(duration / 4);
    			squashAnim1.setRepeatCount(1);
    			squashAnim1.setRepeatMode(ValueAnimator.REVERSE);
    			squashAnim1.setInterpolator(new DecelerateInterpolator());
    			ValueAnimator squashAnim2 = ObjectAnimator.ofFloat(newBall,
    					"width", newBall.getWidth(), newBall.getWidth() + 50);
    			squashAnim2.setDuration(duration / 4);
    			squashAnim2.setRepeatCount(1);
    			squashAnim2.setRepeatMode(ValueAnimator.REVERSE);
    			squashAnim2.setInterpolator(new DecelerateInterpolator());
    			ValueAnimator stretchAnim1 = ObjectAnimator.ofFloat(newBall, "y",
    					endY, endY + 25f);
    			stretchAnim1.setDuration(duration / 4);
    			stretchAnim1.setRepeatCount(1);
    			stretchAnim1.setInterpolator(new DecelerateInterpolator());
    			stretchAnim1.setRepeatMode(ValueAnimator.REVERSE);
    			ValueAnimator stretchAnim2 = ObjectAnimator.ofFloat(newBall,
    					"height", newBall.getHeight(), newBall.getHeight() - 25);
    			stretchAnim2.setDuration(duration / 4);
    			stretchAnim2.setRepeatCount(1);
    			stretchAnim2.setInterpolator(new DecelerateInterpolator());
    			stretchAnim2.setRepeatMode(ValueAnimator.REVERSE);
    			ValueAnimator bounceBackAnim = ObjectAnimator.ofFloat(newBall, "y",
    					endY, startY);
    			bounceBackAnim.setDuration(duration);
    			bounceBackAnim.setInterpolator(new DecelerateInterpolator());
    			// Sequence the down/squash&stretch/up animations
    			AnimatorSet bouncer = new AnimatorSet();
    			bouncer.play(bounceAnim).before(squashAnim1);
    			bouncer.play(squashAnim1).with(squashAnim2);
    			bouncer.play(squashAnim1).with(stretchAnim1);
    			bouncer.play(squashAnim1).with(stretchAnim2);
    			bouncer.play(bounceBackAnim).after(stretchAnim2);
    
    			// Fading animation - remove the ball when the animation is done
    			ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha",
    					1f, 0f);
    			fadeAnim.setDuration(250);
    			fadeAnim.addListener(new AnimatorListenerAdapter() {
    				@Override
    				public void onAnimationEnd(Animator animation) {
    					balls.remove(((ObjectAnimator) animation).getTarget());
    
    				}
    			});
    
    			// Sequence the two animations to play one after the other
    			AnimatorSet animatorSet = new AnimatorSet();
    			animatorSet.play(bouncer).before(fadeAnim);
    
    			// Start the animation
    			animatorSet.start();
    
    			return true;
    		}
    
    		private ShapeHolder addBall(float x, float y) {
    			OvalShape circle = new OvalShape();
    			circle.resize(50f, 50f);
    			ShapeDrawable drawable = new ShapeDrawable(circle);
    			ShapeHolder shapeHolder = new ShapeHolder(drawable);
    			shapeHolder.setX(x - 25f);
    			shapeHolder.setY(y - 25f);
    			int red = (int) (Math.random() * 255);
    			int green = (int) (Math.random() * 255);
    			int blue = (int) (Math.random() * 255);
    			int color = 0xff000000 | red << 16 | green << 8 | blue;
    			Paint paint = drawable.getPaint(); // new
    												// Paint(Paint.ANTI_ALIAS_FLAG);
    			int darkColor = 0xff000000 | red / 4 << 16 | green / 4 << 8 | blue
    					/ 4;
    			RadialGradient gradient = new RadialGradient(37.5f, 12.5f, 50f,
    					color, darkColor, Shader.TileMode.CLAMP);
    			paint.setShader(gradient);
    			shapeHolder.setPaint(paint);
    			balls.add(shapeHolder);
    			return shapeHolder;
    		}
    
    		@Override
    		protected void onDraw(Canvas canvas) {
    			for (int i = 0; i < balls.size(); ++i) {
    				ShapeHolder shapeHolder = balls.get(i);
    				canvas.save();
    				canvas.translate(shapeHolder.getX(), shapeHolder.getY());
    				shapeHolder.getShape().draw(canvas);
    				canvas.restore();
    			}
    		}
    	}
    
    }
    

      

    自定义

    ShapeHolder 

    如下:

    /*
     * Copyright (C) 2010 The Android Open Source Project
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    package com.edaixi.tempbak;
    
    import android.graphics.Paint;
    import android.graphics.RadialGradient;
    import android.graphics.drawable.ShapeDrawable;
    import android.graphics.drawable.shapes.Shape;
    
    /**
     * A data structure that holds a Shape and various properties that can be used to define
     * how the shape is drawn.
     */
    public class ShapeHolder {
        private float x = 0, y = 0;
        private ShapeDrawable shape;
        private int color;
        private RadialGradient gradient;
        private float alpha = 1f;
        private Paint paint;
    
        public void setPaint(Paint value) {
            paint = value;
        }
        public Paint getPaint() {
            return paint;
        }
    
        public void setX(float value) {
            x = value;
        }
        public float getX() {
            return x;
        }
        public void setY(float value) {
            y = value;
        }
        public float getY() {
            return y;
        }
        public void setShape(ShapeDrawable value) {
            shape = value;
        }
        public ShapeDrawable getShape() {
            return shape;
        }
        public int getColor() {
            return color;
        }
        public void setColor(int value) {
            shape.getPaint().setColor(value);
            color = value;
        }
        public void setGradient(RadialGradient value) {
            gradient = value;
        }
        public RadialGradient getGradient() {
            return gradient;
        }
    
        public void setAlpha(float alpha) {
            this.alpha = alpha;
            shape.setAlpha((int)((alpha * 255f) + .5f));
        }
    
        public float getWidth() {
            return shape.getShape().getWidth();
        }
        public void setWidth(float width) {
            Shape s = shape.getShape();
            s.resize(width, s.getHeight());
        }
    
        public float getHeight() {
            return shape.getShape().getHeight();
        }
        public void setHeight(float height) {
            Shape s = shape.getShape();
            s.resize(s.getWidth(), height);
        }
    
        public ShapeHolder(ShapeDrawable s) {
            shape = s;
        }
    }
    

      

    自定义Layout布局渐变背景如下:

    package com.edaixi.tempbak;
    
    import android.animation.ArgbEvaluator;
    import android.animation.ObjectAnimator;
    import android.animation.ValueAnimator;
    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.util.AttributeSet;
    import android.widget.RelativeLayout;
    
    @SuppressLint("NewApi")
    public class CustomerRelativeLayout extends RelativeLayout {
    	private static final int RED = 0xffFF8080;
    	private static final int BLUE = 0xff8080FF;
    
    	public CustomerRelativeLayout(Context context) {
    		super(context);
    		setBg();
    	}
    
    	public CustomerRelativeLayout(Context context, AttributeSet attrs,
    			int defStyleAttr, int defStyleRes) {
    		super(context, attrs, defStyleAttr, defStyleRes);
    		setBg();
    	}
    
    	public CustomerRelativeLayout(Context context, AttributeSet attrs,
    			int defStyleAttr) {
    		super(context, attrs, defStyleAttr);
    		setBg();
    	}
    
    	public CustomerRelativeLayout(Context context, AttributeSet attrs) {
    		super(context, attrs);
    		setBg();
    	}
    
    	public void setBg() {
    		ValueAnimator colorAnim = ObjectAnimator.ofInt(this, "backgroundColor",
    				RED, BLUE);
    		colorAnim.setDuration(3000);
    		colorAnim.setEvaluator(new ArgbEvaluator());
    		colorAnim.setRepeatCount(ValueAnimator.INFINITE);
    		colorAnim.setRepeatMode(ValueAnimator.REVERSE);
    		colorAnim.start();
    	}
    }
    

      

    布局中引用即可“

    <?xml version="1.0" encoding="utf-8"?>
    <com.edaixi.tempbak.CustomerRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/rl_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
    
    </com.edaixi.tempbak.CustomerRelativeLayout>
    

      

  • 相关阅读:
    Java高级之类结构的认识
    14.8.9 Clustered and Secondary Indexes
    14.8.4 Moving or Copying InnoDB Tables to Another Machine 移动或者拷贝 InnoDB 表到另外机器
    14.8.3 Physical Row Structure of InnoDB Tables InnoDB 表的物理行结构
    14.8.2 Role of the .frm File for InnoDB Tables InnoDB 表得到 .frm文件的作用
    14.8.1 Creating InnoDB Tables 创建InnoDB 表
    14.7.4 InnoDB File-Per-Table Tablespaces
    14.7.2 Changing the Number or Size of InnoDB Redo Log Files 改变InnoDB Redo Log Files的数量和大小
    14.7.1 Resizing the InnoDB System Tablespace InnoDB 系统表空间大小
    14.6.11 Configuring Optimizer Statistics for InnoDB 配置优化统计信息用于InnoDB
  • 原文地址:https://www.cnblogs.com/spring87/p/4496930.html
Copyright © 2011-2022 走看看