總歸是逮着機會,稍微慢一點。在過去的很長一段時間內,都是在業務邏輯的複雜變化中掙扎。沒有技術上的成長,內心還是蠻恐慌的。一不小心,又帶有了些許的情緒在裏面。。。。。
一、屬性動畫單個動畫
1,佈局文件添加動畫作用目標
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.future.animatordemo.MainActivity">
<ImageView
android:id="@+id/content_iv"
android:layout_width="150dp"
android:layout_height="150dp"
android:src="@mipmap/koala" />
</RelativeLayout>
2,獲取控件並執行動畫
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
/**
* 圖片
*/
private ImageView contentIV;
/**
* 自定義控件
*/
private PointView createView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_bak);
initView();
initAnimation();
initListener();
}
/**
* 初始化控件
*/
private void initView() {
contentIV = findViewById(R.id.content_iv);
}
/**
* 初始化動畫
*/
private void initAnimation() {
rotateAnimation();
//alpahAnimation();
}
private void initListener() {
contentIV.setOnClickListener(this);
}
/**
* 旋轉動畫
*/
private void rotateAnimation() {
ObjectAnimator anim = ObjectAnimator.ofFloat(contentIV, "rotation", 0f, 360f);
anim.setDuration(1000);
anim.start();
}
/**
* 透明漸變動畫
*/
private void alpahAnimation() {
ObjectAnimator anim = ObjectAnimator.ofFloat(contentIV, "alpha", 1.0f, 0.8f, 0.6f, 0.4f, 0.2f, 0.0f);
anim.setRepeatCount(-1);
anim.setRepeatMode(ObjectAnimator.REVERSE);
anim.setDuration(2000);
anim.start();
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.content_iv:
Toast.makeText(MainActivity.this, "戳中朕心了~_~", Toast.LENGTH_SHORT).show();
break;
}
}
}
執行效果:
旋轉動畫:
透明漸變動畫:
二、屬性動畫的合集
添加以下方法,並在onCreate()中調用
private void setAnimation() {
ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(contentIV, "alpha", 1.0f, 0.5f, 0.8f, 1.0f);
ObjectAnimator scaleXAnim = ObjectAnimator.ofFloat(contentIV, "scaleX", 0.0f, 1.0f);
ObjectAnimator scaleYAnim = ObjectAnimator.ofFloat(contentIV, "scaleY", 0.0f, 2.0f, 1.0f);
ObjectAnimator rotateAnim = ObjectAnimator.ofFloat(contentIV, "rotation", 0, 360);
ObjectAnimator transXAnim = ObjectAnimator.ofFloat(contentIV, "translationX", 100, 400);
ObjectAnimator transYAnim = ObjectAnimator.ofFloat(contentIV, "translationY", 100, 750, 300, 600);
AnimatorSet set = new AnimatorSet();
set.playTogether(alphaAnim, scaleXAnim, scaleYAnim, rotateAnim, transXAnim, transYAnim);//疊加在一起運動
// set.playSequentially(alphaAnim, scaleXAnim, scaleYAnim, rotateAnim, transXAnim, transYAnim);
set.setDuration(3000);
set.start();
}
其中playTogether()將所有的動畫組合在一起,同時開啓動畫。playSequentially()將動畫順序執行,當上一個動畫沒有結束時,下一個動畫不會開始執行。
展示效果:
三、屬性動畫的監聽
代碼修改,添加動畫運行更新監聽,並在更新方法中刷新控件狀態。使用了Layout()方法。
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
/**
* 圖片
*/
private ImageView contentIV;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initListener();
}
/**
* 初始化控件
*/
private void initView() {
contentIV = findViewById(R.id.content_iv);
}
private void initListener() {
contentIV.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.content_iv:
Toast.makeText(MainActivity.this, "戳中朕心了~_~", Toast.LENGTH_SHORT).show();
break;
}
}
public void startAnimatorAnimation(View view) {
ValueAnimator animator = ValueAnimator.ofInt(0, 400);
animator.setDuration(1000);
animator.setInterpolator(new DecelerateInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int curValue = (int) animation.getAnimatedValue();
contentIV.layout(curValue, curValue, curValue + contentIV.getWidth(), curValue + contentIV.getHeight());
}
});
animator.setStartDelay(1000);
animator.start();
}
}
備註:
相比於補間動畫,屬性動畫直接修改了控件屬性。直接反饋就是點擊事件在補間動畫時,只有在控件開始的位置執行纔有效,其他地方無效。而屬性動畫在運行過程中,控件所在位置就是響應事件響應位置。
展示效果:
四、屬性動畫的應用
依據以上學習內容,製作自定義控件,展示屬性動畫的應用。
自定義控件實現如下:
public class PointView extends View {
public static final float RADIUS = 20f;
private Point currentPoint;
private Paint mPaint;
private Paint linePaint;
private AnimatorSet animSet;
private TimeInterpolator interpolatorType = new LinearInterpolator();
/**
* 實現關於color 的屬性動畫
*/
private int color;
private float radius = RADIUS;
public PointView(Context context) {
super(context);
init();
}
public PointView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public PointView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
mPaint.setColor(this.color);
}
public float getRadius() {
return radius;
}
public void setRadius(float radius) {
this.radius = radius;
}
private void init() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(Color.TRANSPARENT);
linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
linePaint.setColor(Color.BLACK);
linePaint.setStrokeWidth(5);
}
@Override
protected void onDraw(Canvas canvas) {
if (currentPoint == null) {
currentPoint = new Point((int) RADIUS, (int) RADIUS);
drawCircle(canvas);
} else {
drawCircle(canvas);
}
drawLine(canvas);
}
private void drawLine(Canvas canvas) {
canvas.drawLine(10, getHeight() / 2, getWidth(), getHeight() / 2, linePaint);
canvas.drawLine(10, getHeight() / 2 - 150, 10, getHeight() / 2 + 150, linePaint);
canvas.drawPoint(currentPoint.x, currentPoint.y, linePaint);
}
public void startAnimation() {
Point startP = new Point((int) RADIUS, (int) RADIUS);
// Point endP = new Point(getWidth() - (int) RADIUS, getHeight() - (int) RADIUS);
Point endP = new Point(MainApplication.getApplication().getWidth() - (int) RADIUS, MainApplication.getApplication().getHeight() - (int) RADIUS);
final ValueAnimator valueAnimator = ValueAnimator.ofObject(new PointSinEvaluator(), startP, endP);
valueAnimator.setRepeatCount(-1);
valueAnimator.setRepeatMode(ValueAnimator.REVERSE);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
currentPoint = (Point) animation.getAnimatedValue();
postInvalidate();
}
});
//
ObjectAnimator animColor = ObjectAnimator.ofObject(this, "color", new ArgbEvaluator(), Color.GREEN,
Color.YELLOW, Color.BLUE, Color.WHITE, Color.RED);
animColor.setRepeatCount(-1);
animColor.setRepeatMode(ValueAnimator.REVERSE);
ValueAnimator animScale = ValueAnimator.ofFloat(20f, 80f, 60f, 10f, 35f, 55f, 10f);
animScale.setRepeatCount(-1);
animScale.setRepeatMode(ValueAnimator.REVERSE);
animScale.setDuration(5000);
animScale.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
radius = (float) animation.getAnimatedValue();
}
});
animSet = new AnimatorSet();
animSet.play(valueAnimator).with(animColor).with(animScale);
animSet.setDuration(5000);
animSet.setInterpolator(interpolatorType);
animSet.start();
}
private void drawCircle(Canvas canvas) {
float x = currentPoint.x;
float y = currentPoint.y;
canvas.drawCircle(x, y, radius, mPaint);
}
public void setInterpolatorType(int type) {
switch (type) {
case 1:
interpolatorType = new BounceInterpolator();
break;
case 2:
interpolatorType = new AccelerateDecelerateInterpolator();
break;
case 3:
interpolatorType = new DecelerateInterpolator();
break;
case 4:
interpolatorType = new AnticipateInterpolator();
break;
case 5:
interpolatorType = new LinearInterpolator();
break;
case 6:
interpolatorType = new LinearOutSlowInInterpolator();
break;
case 7:
interpolatorType = new OvershootInterpolator();
default:
interpolatorType = new LinearInterpolator();
break;
}
}
@TargetApi(Build.VERSION_CODES.KITKAT)
public void pauseAnimation() {
if (animSet != null) {
animSet.pause();
}
}
public void stopAnimation() {
if (animSet != null) {
animSet.cancel();
this.clearAnimation();
}
}
}
XML文件中使用:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.future.animatordemo.MainActivity">
<ImageView
android:id="@+id/content_iv"
android:layout_width="150dp"
android:layout_height="150dp"
android:src="@mipmap/koala" />
<com.future.animatordemo.view.PointView
android:id="@+id/create_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
初始化控件並使用控件:
public class MainActivityBak extends AppCompatActivity implements View.OnClickListener {
/**
* 圖片
*/
private ImageView contentIV;
/**
* 自定義控件
*/
private PointView createView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_bak);
initView();
initAnimation();
initListener();
}
/**
* 初始化控件
*/
private void initView() {
contentIV = findViewById(R.id.content_iv);
createView = findViewById(R.id.create_view);
}
/**
* 初始化動畫
*/
private void initAnimation() {
setAnimation();
createView.startAnimation();
}
private void initListener() {
contentIV.setOnClickListener(this);
}
private void setAnimation() {
ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(contentIV, "alpha", 1.0f, 0.5f, 0.8f, 1.0f);
ObjectAnimator scaleXAnim = ObjectAnimator.ofFloat(contentIV, "scaleX", 0.0f, 1.0f);
ObjectAnimator scaleYAnim = ObjectAnimator.ofFloat(contentIV, "scaleY", 0.0f, 2.0f, 1.0f);
ObjectAnimator rotateAnim = ObjectAnimator.ofFloat(contentIV, "rotation", 0, 360);
ObjectAnimator transXAnim = ObjectAnimator.ofFloat(contentIV, "translationX", 100, 400);
ObjectAnimator transYAnim = ObjectAnimator.ofFloat(contentIV, "translationY", 100, 750, 300, 600);
AnimatorSet set = new AnimatorSet();
set.playTogether(alphaAnim, scaleXAnim, scaleYAnim, rotateAnim, transXAnim, transYAnim);//疊加在一起運動
// set.playSequentially(alphaAnim, scaleXAnim, scaleYAnim, rotateAnim, transXAnim, transYAnim);
set.setDuration(3000);
set.start();
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.content_iv:
Toast.makeText(MainActivity.this, "戳中朕心了~_~", Toast.LENGTH_SHORT).show();
break;
}
}
}
展示效果:
有人請教我哆啦A夢和大雄最後有沒有在一起,我便問他,許仙最後有沒有和白蛇在一起。生之有涯‘最後'如何,也不過是蜿蜒個幾十年的一件小事,而大事是他們,和我們曾經在一起過。
所有被千夫所指的困難,都是爲了淘汰掉懦夫!