Android中自定义View和自定义动画

来源:互联网 发布:zbrush mac 破解教程 编辑:程序博客网 时间:2024/04/29 08:11

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}/*@Overridepublic void onClick(View v) {//加载动画资源//final Animation anim = AnimationUtils.loadAnimation(context, R.anim.myanim);startAnimation(new MyAnimation());System.out.println("我点了");}*/@Overridepublic 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(){@Overridepublic void onAnimationEnd(Animation animation) {// TODO Auto-generated method stub//LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(20, 20);setLayoutParams(params);setBackgroundResource(R.drawable.ic_launcher);}@Overridepublic void onAnimationRepeat(Animation animation) {// TODO Auto-generated method stub}@Overridepublic 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);}@Overridepublic 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());}@Overrideprotected 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();}}

6 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 魅蓝note5卡顿怎么办 魅蓝note5卡了怎么办 魅蓝note5很卡怎么办 魅蓝note5锁了怎么办 荣耀9开不开机怎么办 4s更新后用不了怎么办 魅蓝3开不了机怎么办 手机不支持联通4g网络怎么办 华为手机出现emui界面怎么办 华为畅玩4x内存不足怎么办 手机电源键掉了怎么办 手机电源键坏了怎么办 小米5s听筒声音小怎么办 荣耀8电源键失灵怎么办 华为荣耀3c卡怎么办 大王卡是2g网络怎么办 联通停用2g副卡怎么办 华为荣耀8忘记解锁密码怎么办 华为手机内存满了怎么办 华为手机无限重启怎么办 华为3c重启怎么办 荣耀6 无限重启怎么办 手机进水无法开机了怎么办 华为手机不停重启怎么办 华为手机反复重启怎么办 酷派电池不耐用怎么办 美图手机充电慢怎么办 酷派b770太卡怎么办 酷派手机出现无命令怎么办 华为荣耀4x卡怎么办 华为手机图案解锁忘了怎么办 xp电脑读不起u盘怎么办 在外国玩王者卡怎么办 华为p7忘记解锁密码怎么办 华为荣耀4x存储空间不足怎么办 红米4a内存不够怎么办 华为h60开不了机怎么办 华为荣耀4c内存不足怎么办 华为4c运行内存不足怎么办 华为手机总是显示内存不足怎么办 华为荣耀4x畅玩版内存不足怎么办