zoukankan      html  css  js  c++  java
  • 图片获得焦点变大并显示在最前方,覆盖后面的图片

    转载请注明出处,谢谢: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();
    
    	@Override
    	protected 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);
    	}
    
    	@Override
    	public void onClick(View v) {
    	}
    	
    	private OnFocusChangeListener focusChangeListener=new OnFocusChangeListener() {
    		
    		@Override
    		public 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方法,位置会错乱。你能够自己去试试。


  • 相关阅读:
    Contest
    【HDU2224】The shortest path(双调欧几里得dp)
    UVa400.Unix ls
    一些脚本
    省赛总结
    一些事
    一些笔记
    CSU 1526: Beam me out!
    以后可能用到的命令
    Codeforces Round #297 (Div. 2)
  • 原文地址:https://www.cnblogs.com/wzzkaifa/p/6918458.html
Copyright © 2011-2022 走看看