Android FrameWork 层给我们提供了很多界面组件,但是在实际的商业开发中这些组件往往并不能完全满足我们的需求,这时候我们就需要自定义我们自己的视图和动画。
我们要重写系统的View就必须了解View的基本用法和结构,如下图所示是Android官方指导中的View结构图:
Android应用的绝大部分UI组件都放在android.widget包及其子包、android.view包及其子包中,Android应用的所有UI组件都继承了View类,View组件非常类似于Swing编程的JPanel,它是所有UI组件的父类,代表一个区域。
View类有一个非常重要的子类叫做ViewGroup,ViewGroup相当于一个专门用来放置View的容器,同样的ViewGroup也继承自View基类,这是一种“组合器”的设计模式。由于ViewGroup也是View的子类,所以ViewGroup内也可以放置ViewGroup,用直观一点的方式解释这句话就如下面的xml文件(LinarLayout就是一个ViewGroup,TextView就是一个View)。
<LinearLayout>
<TextView></TextView>
<LinearLayout></LinearLayout>
</LinearLayout>
下面来介绍一下View和ViewGroup中的几个重要的方法
(1)onDraw :绘制自己
(2)onLayout:View中布局发生改变时会调用此方法
(3)dispatchDraw:用于控制子View的绘制分发
(4)drawChild:直接控制具体的子View
重写一个View的步骤如下:
(1)新建一个View子类,并实现构造
package com.example.testmyanimation;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.LinearInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
public class MyButton extends Button{
private Context context;
private LayoutParams params;
public MyButton(Context context) {
super(context);
this.context = context;
//setOnClickListener(this);
// TODO Auto-generated constructor stub
}
public MyButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
//setOnClickListener(this);
// TODO Auto-generated constructor stub
}
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
//setOnClickListener(this);
// TODO Auto-generated constructor stub
}
/*@Override
public void onClick(View v) {
//加载动画资源
//final Animation anim = AnimationUtils.loadAnimation(context, R.anim.myanim);
startAnimation(new MyAnimation());
System.out.println("我点了");
}*/
@Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN){
WindowManager windowManager = (WindowManager) getContext()
.getSystemService(Context.WINDOW_SERVICE);
int width = windowManager.getDefaultDisplay().getWidth();
int height = windowManager.getDefaultDisplay().getHeight();
float x = event.getRawX() - event.getX();
float y = event.getRawY() -event.getY();
//MyAnimation mAnimation = new MyAnimation(width - x , height - y, 1000);
AnimationSet mAnimation=new AnimationSet(false);
TranslateAnimation translateAnimationX=new TranslateAnimation(0, width - x, 0, 0);
translateAnimationX.setInterpolator(new LinearInterpolator());
// translateAnimationX.setRepeatCount(200);
TranslateAnimation translateAnimationY=new TranslateAnimation(0, 0, 0, height - y);
translateAnimationY.setInterpolator(new AccelerateInterpolator());
// translateAnimationY.setRepeatCount(200);
mAnimation.addAnimation(translateAnimationY);
mAnimation.addAnimation(translateAnimationX);
mAnimation.setDuration(500);
mAnimation.setAnimationListener(new Animation.AnimationListener(){
@Override
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
//LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(20, 20);
setLayoutParams(params);
setBackgroundResource(R.drawable.ic_launcher);
}
@Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationStart(Animation animation) {
params = (LayoutParams) getLayoutParams();
LinearLayout.LayoutParams layout_params = new LinearLayout.LayoutParams(20, 20);
setLayoutParams(layout_params);
setBackgroundResource(R.drawable.b1);
}});
startAnimation(mAnimation);
}
return true;
}
}
(2)在xml文件中使用如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.example.testmyanimation.MyButton
android:id="@+id/mybutton"
android:layout_width="40dip"
android:layout_height="30dip"/>
<com.example.testmyanimation.MyButton
android:layout_width="40dip"
android:layout_height="30dip"/>
<com.example.testmyanimation.MyButton
android:layout_width="30dip"
android:layout_height="30dip"/>
</LinearLayout>
下面来介绍一下Animation及重写Animation,在Android中使用Animation代表抽象的动画类,它包括如下几个子类:
(1)AlphaAnimation :透明度改变的动画。
(2)ScaleAnimation:大小缩放的动画。
(3)TranslateAnimation:位移变化的动画。
(4)RotateAnimation:旋转动画。
然而在实际项目中透明度、缩放、位移、旋转这几种动画并不能满足我们的需求,这时候就需要用到自定义动画,自定义动画需要继承Animation,并重写applyTransformation(float interpolatedTime, Transformation t)方法,该方法中的两个参数说明:
interpolatedTime:该参数代表了时间的进行程度(如:你设置的时间是1000ms, 那么interploatedTime就会从0开始一直到1)
Transformation:代表补间动画在不同时刻对图形或组建的变形程度。该对象中封装了一个Matrix对象,对它所包含的Matrix对象进行位移、倾斜、旋转等变换时,Transformation将会控制对应的图片或视图进行相应的变换。
为了控制图片或View进行三维空间的变换,还需要借助于Android提供的一个Camera类,该类是一个空间变换工具,作用有点类似于Matrix,提供了如下常用的方法。
getMatrix(Matrix matrix) :将Camera所做的变换应用到指定的maxtrix上
rotateX(float deg):将目标组件沿X轴旋转
rotateY(float deg)、rotateZ(float deg)
translate(float x, float y, float z):把目标组件在三维空间类进行位移变换。
applyToCanvas(Canvas canvas):把Camera所做的变换应用到Canvas上。
具体自定义实现如下:
package com.example.testmyanimation;
import android.content.Context;
import android.graphics.Camera;
import android.graphics.Matrix;
import android.util.AttributeSet;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.Transformation;
public class MyAnimation extends Animation{
private float moveX;
private float moveY;
private int duration;
private Camera camera = new Camera();
public MyAnimation(float moveX, float moveY, int duration) {
this.moveX = moveX;
this.moveY = moveY;
this.duration = duration;
}
public MyAnimation(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void initialize(int width, int height, int parentWidth,
int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
//设置动画的持续时间
setDuration(duration);
//设置动画结束后保留效果
setFillAfter(false);
//setRepeatCount(2);
//setRepeatMode(2);
//播放速度
setInterpolator(new MyInterprolator());
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
camera.save();
camera.translate(0f + moveX * interpolatedTime,
0f - moveY * interpolatedTime,
0f);
//camera.rotateY(360 * (interpolatedTime) * 2);
//camera.rotateX(360 * (interpolatedTime));
//camera.rotateZ(360 * (interpolatedTime));
Matrix matrix = t.getMatrix();
camera.getMatrix(matrix);
//matrix.preTranslate(-centerX, -centerY);
//matrix.postTranslate(centerX, centerY);
camera.restore();
}
}
分享到:
相关推荐
该项目使用AS开发,通过获取当前系统时间,然后通过自定义View加自定义的属性动画ValueAnimator实现了一个带动画效果的时钟,对学习自定义View是一个很好的例子
Android自定义view,实现动画效果
Android自定义动画View的实现。
android自定义ImageView实现旋转动画
本示例是一个Android应用程序。通过自定义View实现动画效果,同时可以利用系统提供的加速器Interpolator控制动画的变化速度。
android studio 自定义button边框,角度,渐变颜色按下时改变样式, 以及基础动画,为image view添加旋转,下移,渐变等样式,使用timer handler button进行控制。
这是一款圆形加载条完之后以波纹动画显示出实物的一款demo,希望对你们有所帮助
BreatheView 呼吸灯闪烁效果的自定义View
Android 自定义view实现签到送积分,7天周期,签到动画
Android按下录音录音动画效果 ,自定义录音、播放动画View
自定义View绘制一个太极旋转图片demo
一个简单的自定义View,用于初步学习Android自定义View,可以参照我的博客http://blog.csdn.net/asdwkl2584561379/article/details/51025998
Android自定义View实现水波纹效果,对Path的学习,实现一个水波纹效果
即兴实现的一个自定义VIew效果,在我的专栏可以看到博文说明:http://blog.csdn.net/column/details/13877.html
Android自定义View-点赞动画效果View-Demo,点赞后,会有动画效果,绘制箭头。
【Android】自定义录音、播放动画View,让你的录音浪起来
Android 粒子效果之雨(自定义View)Android 自定义 View 基础和原理实现 1.绘制下雨场景的个体、雨点(直线) 2.让直线动起来 3.处理边界问题 4.构造雨点对象 5.雨点大小设置 6.速度设置和角度设置等 7.添加多个...
这里有很多自定义view可以参考思路思路比较简单,整个view无非两样东西云雨滴这里又包含两部分动画,一部分是云的左右移动动画,一部分是雨滴移动动画 那我们这里可以自定义一些属性,如果对自定义属性还不太了解的...
由圆角矩形view点击后渐变为圆形旋转进度view,再次点击变回原样
安卓自定义View,实现点赞爆炸效果,里面有酷炫的动画!