圖片獲得焦點變大並顯示在最前方,覆蓋後面的圖片,焦點覆蓋
轉載請註明出處,謝謝:http://blog.csdn.net/harryweasley/article/details/46678315
提前聲明:本篇部落格是基於電視機頂盒的,全部操作是用遙控器。
先看下
如所示,圖片放大,並且在最前方,可以遮蓋住後面的圖片。
在做放大效果之前,我們先建立一個類ScaleAnimEffect。
package com.amt.appstore.activity;import android.view.animation.AccelerateInterpolator;import android.view.animation.Animation;import android.view.animation.ScaleAnimation;public class ScaleAnimEffect {private long duration;private float fromAlpha;private float fromXScale;private float fromYScale;private float toAlpha;private float toXScale;private float toYScale;public void setAttributs(float paramFloat1, float paramFloat2,float paramFloat3, float paramFloat4, long paramLong) {this.fromXScale = paramFloat1;this.fromYScale = paramFloat3;this.toXScale = paramFloat2;this.toYScale = paramFloat4;this.duration = paramLong;}public Animation createAnimation() {/** * @param fromX * 動畫開始前水平方向的伸縮比例大小 * @param toX * 動畫結束後,水平方向的伸縮比例大小 * @param fromY * 動畫開始前,豎直方向的比例大小 * @param toY * 動畫結束結束後,豎直方向的比例大小 * @param pivotXType * 指定pivotXValue以哪個為座標點為中心來旋轉。 Animation.ABSOLUTE, * Animation.RELATIVE_TO_SELF, 或者 * Animation.RELATIVE_TO_PARENT這三個其中之一。 * @param pivotXValue * 正在伸縮的對象的點的x座標,指定為絕對數,並且0是左邊緣(當對象改變尺寸的時候,點保持不變。) * 如果pivotXType是 * Animation.ABSOLUTE,這個值既可以是絕對數,也可以為百分數(1.0位100%) * * @param pivotYType * 指定pivotYValue以哪個為座標點為中心來旋轉。 Animation.ABSOLUTE, * Animation.RELATIVE_TO_SELF, 或者 * Animation.RELATIVE_TO_PARENT這三個其中之一。 * @param pivotYValue * 正在伸縮的對象的點的y座標,指定為絕對數,並且0是左邊緣(當對象改變尺寸的時候,點保持不變。) * 如果pivotYType是 * Animation.ABSOLUTE,這個值既可以是絕對數,也可以為百分數(1.0位100%) */ScaleAnimation localScaleAnimation = new ScaleAnimation(this.fromXScale, this.toXScale, this.fromYScale, this.toYScale,Animation.RELATIVE_TO_SELF, 0.5F, Animation.RELATIVE_TO_SELF,0.5F);// 動畫執行完成後,是否停留在執行完的狀態localScaleAnimation.setFillAfter(true);// 在動畫開始的地方速率比較慢,然後開始加速localScaleAnimation.setInterpolator(new AccelerateInterpolator());// 設定動畫期間localScaleAnimation.setDuration(this.duration);return localScaleAnimation;}}
關於Interpolator,被用於修飾動畫效果,定義動畫的變動率。
AccelerateDecelerateInterpolator 在動畫開始與結束的地方速率改變比較慢,在中間的時候加速
AccelerateInterpolator 在動畫開始的地方速率改變比較慢,然後開始加速
AnticipateInterpolator 開始的時候向後然後向前甩
AnticipateOvershootInterpolator 開始的時候向後然後向前甩一定值後返回最後的值
BounceInterpolator 動畫結束的時候彈起
CycleInterpolator 動畫迴圈播放特定的次數,速率改變沿著正弦曲線
DecelerateInterpolator 在動畫開始的地方快然後慢
LinearInterpolator 以常量速率改變
OvershootInterpolator 向前甩一定值後再回到原來位置
關於ScaleAnimation的建構函式後面四個參數,我是真的頭大,經過看官方的翻譯,還是有點雲裡霧裡,就先這樣定義吧。
接下來看xml布局檔案activity_increase.xml。
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="fill_parent" > <FrameLayout android:id="@+id/flid1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginTop="10dp" android:focusable="false" > <ImageView android:id="@+id/itvimageid1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:focusable="true" android:focusableInTouchMode="true" android:scaleType="fitXY" android:src="@drawable/ic_empty" /> </FrameLayout> <FrameLayout android:id="@+id/flid2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="80dp" android:layout_marginTop="10dp" android:focusable="false" > <ImageView android:id="@+id/itvimageid2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:focusable="true" android:focusableInTouchMode="true" android:scaleType="fitXY" android:src="@drawable/ic_error" /> </FrameLayout> <FrameLayout android:id="@+id/flid3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="160dp" android:layout_marginTop="10dp" android:focusable="false" > <ImageView android:id="@+id/itvimageid3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:focusable="true" android:focusableInTouchMode="true" android:scaleType="fitXY" android:src="@drawable/ic_stub" /> </FrameLayout></RelativeLayout>
這裡之所以用relativeLayout布局,而不用LinearLayout布局直接放入這三個FrameLayout,因為在之後的IncreaseActivity用到了一個方法bringToFront(),關於這個方法,之後講解。
最後是IncreaseActivity
package com.example.test;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.view.View.OnFocusChangeListener;import android.view.animation.Animation;import android.widget.FrameLayout;import android.widget.ImageView;public class IncreaseActivity extends Activity implements OnClickListener {public static final int COLUMN_IMAGE_COUNT = 3;ImageView columnImages[] = new ImageView[COLUMN_IMAGE_COUNT];FrameLayout mFrameLayout[]=new FrameLayout[COLUMN_IMAGE_COUNT];ScaleAnimEffect animEffect = new ScaleAnimEffect();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_increase);findviewbyid();//給圖片註冊焦點改變監聽for (int i = 0; i < COLUMN_IMAGE_COUNT; i++) { columnImages[i].setOnFocusChangeListener(focusChangeListener); columnImages[i].setOnClickListener(this);}}public void findviewbyid() {columnImages[0] = (ImageView) findViewById(R.id.itvimageid1);columnImages[1] = (ImageView) findViewById(R.id.itvimageid2);columnImages[2] = (ImageView) findViewById(R.id.itvimageid3);mFrameLayout[0] = (FrameLayout) findViewById(R.id.flid1);mFrameLayout[1] = (FrameLayout) findViewById(R.id.flid2);mFrameLayout[2] = (FrameLayout) findViewById(R.id.flid3);}@Overridepublic void onClick(View v) {}private OnFocusChangeListener focusChangeListener=new OnFocusChangeListener() {@Overridepublic void onFocusChange(View v, boolean hasFocus) { switch(v.getId()){ case R.id.itvimageid1:if (hasFocus) {showOnFocusAnimation(0);return;}showLooseFocusAinimation(0);return;case R.id.itvimageid2:if (hasFocus) {showOnFocusAnimation(1);return;}showLooseFocusAinimation(1);return;case R.id.itvimageid3:if (hasFocus) {showOnFocusAnimation(2);return;}showLooseFocusAinimation(2);return; }}};/** * 擷取焦點後執行的方法 * @param i */private void showOnFocusAnimation(int i) {//將該控制項移到最前面mFrameLayout[i].bringToFront();this.animEffect.setAttributs(1.0F, 1.25F, 1.0F, 1.25F, 100L);Animation localAnimation = this.animEffect.createAnimation();this.mFrameLayout[i].startAnimation(localAnimation);}/** * 失去焦點後執行的方法 * @param i */private void showLooseFocusAinimation(int i) {animEffect.setAttributs(1.25F, 1.0F, 1.25F, 1.0F, 0L);mFrameLayout[i].startAnimation(animEffect.createAnimation());}}
關於這裡的bringToFront()方法,Android中的ViewGroup是通過一個Array來儲存其Children,當調用某個childView的bringToFront時,是將該childView放在其Parent的Array數組的最後,ViewGroup的dispatchDraw在draw時是按照Array從前往後依次調用drawChild的,這樣最後一個childView就在最前面了。這也是為什麼要用relativeLayout來布局,而不是用LinearLayout來布局。
如果是LinearLayout布局,調用bringToFront方法,位置會錯亂,你可以自己去試試。
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。