編輯:關於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不僅僅是手機,不僅可以做智能手機,下載
過濾操作符3.1 filter符合某種規則的Observable才會向下傳遞,例子 Observable.range(100,10).filter(new Fun
先看下面圖片:這是我在做登錄頁面的時候,調用系統的ProgressDialog 進行等待,可是看起來很不協調,左邊的等待圖片過大,右邊文字過小,看起來老別扭,雖然功能上不
在定義了將要被OpenGL繪制的形狀之後,你當然想要繪制它們。使用OpenGL ES 2.0繪制圖形需要的代碼可能比你想象的要多,因為API提供了大量的圖形渲染管道控制接