編輯:關於Android編程
前面寫過《墨跡天氣3.0引導界面及動畫實現》,裡面完美實現了動畫效果,那一篇文章使用的View Animation,這一篇文章使用的Property Animation實現。Property Animation是Android3.0以後新增的動畫庫。
這篇文章的源碼以及效果在github。
實現墨跡天氣向上滑動的viewpager使用的開源庫ViewPager-Android。ViewPager-Android開源庫設置app:orientation定義滑動方向。
墨跡天氣引導界面共有4個視圖,先看一下:(這裡引入的圖片都是實現後的,截圖都是靜態圖,運行程序看動畫效果)。

圖一 圖二

圖三 圖四
墨跡天氣的引導界面使用的無非是移動、漸變、縮放、轉動或者其中幾個的組合。我們介紹其中的部分實現。
首先是圖一的“極低耗電”使用了一個縮放效果,使用Property Animation實現如下:
xml動畫文件:
java使用:
animation1=(AnimatorSet)AnimatorInflater.loadAnimator(PropertyAnimActivity.this, R.animator.tutorail_rotate); LinearInterpolator lin = new LinearInterpolator(); animation1.setInterpolator(lin); t1_icon2.setVisibility(View.VISIBLE); animation1.setTarget(t1_icon2); animation1.start();
圖一中下面的箭頭使用了移動漸變組合動畫,實現如下:
xml文件:
Java調用動畫資源和前面是一樣的,不做過多說明。
圖1中間使用了旋轉縮放組合動畫,,實現如下:
Java調用動畫資源和前面是一樣的,不做過多說明。
4、平移動畫
圖三更多的使用了平移動畫,因為要計算位置,沒有使用xml資源文件,Java實現:
transAnimationX2=ObjectAnimator.ofFloat(t3_icon2, translationX, fx1, tx1);
transAnimationX2.setDuration(800);
transAnimationX2.setRepeatCount(Animation.INFINITE);// Animation.INFINITE
transAnimationX2.setRepeatMode(Animation.RESTART);
transAnimationX2.setInterpolator(new LinearInterpolator());
transAnimationY2=ObjectAnimator.ofFloat(t3_icon2, translationY, fy1, ty1);
transAnimationY2.setDuration(800);
transAnimationY2.setRepeatCount(Animation.INFINITE);// Animation.INFINITE
transAnimationY2.setRepeatMode(Animation.RESTART);
transAnimationY2.setInterpolator(new LinearInterpolator());
PropertyValuesHolder pvhX3 = PropertyValuesHolder.ofFloat(translationX, fx2, tx2);
PropertyValuesHolder pvhY3 = PropertyValuesHolder.ofFloat(translationY, fy2, ty2);
transAnimation3=ObjectAnimator.ofPropertyValuesHolder(t3_icon3, pvhX3, pvhY3);
transAnimation3.setDuration(1200);
transAnimation3.setRepeatCount(Animation.INFINITE);
transAnimation3.setRepeatMode(Animation.RESTART);
transAnimation3.setInterpolator((new LinearInterpolator()));
PropertyValuesHolder pvhX4 = PropertyValuesHolder.ofFloat(translationX, fx3, tx3);
PropertyValuesHolder pvhY4 = PropertyValuesHolder.ofFloat(translationY, fy3, ty3);
transAnimation4=ObjectAnimator.ofPropertyValuesHolder(t3_icon4, pvhX4, pvhY4);
transAnimation4.setDuration(1200);
transAnimation4.setRepeatCount(Animation.INFINITE);
transAnimation4.setRepeatMode(Animation.RESTART);
transAnimation4.setInterpolator((new LinearInterpolator()));
PropertyValuesHolder pvhX5 = PropertyValuesHolder.ofFloat(translationX, fx4, tx4);
PropertyValuesHolder pvhY5 = PropertyValuesHolder.ofFloat(translationY, fy4, ty4);
transAnimation5=ObjectAnimator.ofPropertyValuesHolder(t3_icon5, pvhX5, pvhY5);
transAnimation5.setDuration(800);
transAnimation5.setRepeatCount(Animation.INFINITE);
transAnimation5.setRepeatMode(Animation.RESTART);
transAnimation5.setInterpolator((new LinearInterpolator()));
flag3=true;
// 延遲1秒
new Handler() {
@Override
public void dispatchMessage(Message msg) {
// TODO Auto-generated method stub
if(flag3)
super.dispatchMessage(msg);
}
public void handleMessage(android.os.Message msg) {
if (msg.what == 1) {
t3_icon2.setVisibility(View.VISIBLE);
t3_icon3.setVisibility(View.VISIBLE);
t3_icon4.setVisibility(View.VISIBLE);
t3_icon5.setVisibility(View.VISIBLE);
transAnimationX2.start();
transAnimationY2.start();
transAnimation3.start();
transAnimation4.start();
transAnimation5.start();
t3_icon6_animationDrawable.start();
}
};
}.sendEmptyMessageDelayed(1, 1000);// 1秒
這個動畫中更重要的是計算初始和結束位置:
view3.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// TODO Auto-generated method stub
int h1 = centerLayout.getTop();
int h2 = centerLayout.getBottom();
DensityUtil densityUtil = new DensityUtil(
PropertyAnimActivity.this);
int w = densityUtil.getScreenWidth();
fx1 = t3_icon2.getTop() + t3_icon2.getHeight();
fy1 = -t3_icon2.getTop() - t3_icon2.getHeight();
tx1 = -t3_icon2.getWidth() - t3_icon2.getLeft();
ty1 = t3_icon2.getTop() + t3_icon2.getLeft()
+ t3_icon2.getWidth();
fx2 = t3_icon3.getTop() + t3_icon3.getHeight();
fy2 = -t3_icon3.getTop() - t3_icon3.getHeight();
tx2 = -t3_icon3.getWidth() - t3_icon3.getLeft();
ty2 = t3_icon3.getTop() + t3_icon3.getLeft()
+ t3_icon3.getWidth();
fx3 = w - t3_icon4.getLeft();
fy3 = -(w - t3_icon4.getLeft());
tx3 = -(h2 - h1 - t3_icon4.getTop());
ty3 = h2 - h1 - t3_icon4.getTop();
fx4 = w - t3_icon5.getLeft();
fy4 = -(w - t3_icon5.getLeft());
tx4 = -(h2 - h1 - t3_icon5.getTop());
ty4 = h2 - h1 - t3_icon5.getTop();
}
});
第四頁動畫中重要的使用了CycleInterpolator(循環插值器)
ObjectAnimator objAnim=ObjectAnimator.ofFloat(t4_icon1, rotation, 0f, 10f); CycleInterpolator interpolator = new CycleInterpolator(3.0f); objAnim.setStartDelay(500); objAnim.setDuration(3000); objAnim.setRepeatCount(Animation.INFINITE);// Animation.INFINITE objAnim.setInterpolator(interpolator); t4_icon1.setPivotX(t4_icon1.getWidth()*0.47f); t4_icon1.setPivotY(t4_icon1.getHeight()*0.05f); objAnim.start();
上面基本實現了墨跡天氣的動畫效果,更多請參考代碼。
華為榮耀6plus紅外遙控功能使用方法
榮耀6plus有著紅外遙控功能,相信入手榮耀6plus的同學都很想試試自己的手機當遙控是什麼感覺吧。華為榮耀6plus不僅僅是手機,不僅可以做智能手機,下載
RxJava過濾操作符實例
過濾操作符3.1 filter符合某種規則的Observable才會向下傳遞,例子 Observable.range(100,10).filter(new Fun
Android Dialog 設置字體大小的具體方法
先看下面圖片:這是我在做登錄頁面的時候,調用系統的ProgressDialog 進行等待,可是看起來很不協調,左邊的等待圖片過大,右邊文字過小,看起來老別扭,雖然功能上不
Android OpenGL ES繪圖教程之三 : 繪制圖形
在定義了將要被OpenGL繪制的形狀之後,你當然想要繪制它們。使用OpenGL ES 2.0繪制圖形需要的代碼可能比你想象的要多,因為API提供了大量的圖形渲染管道控制接