Android动画被父View遮挡的解决办法。

    Android的Animation动画想必大家非常熟悉,也相对是比较好用的动画方式。但是这个动画有个很大的缺点,这个动画无法再使用动画的View的父组件之外使用。这个是Animation的实现方式导致的,由于View是由其父组件绘制,而Animation也不过是不断改变位置然后在不断刷新而已,所以仍然没有摆脱是由其父View进行绘制的根本,所以无论如何View是不能超出其父View的边界显示的。这条路行不通。

    这里我们就要从根本出发,我们为什么要让动画超出父组件,如果父组件是和屏幕一样大ViewGroup,我们还需要超出去么?当然不需要了。所以,我们需要使用动画的一般都是个小ViewGroup中的一个View。这里我们就要转化一下思路,无论这个View在哪里,上边有几层父view,我们不去管它。我们只需要建立一个副本(或者取出这个View)放在最大的ViewGroup(足够执行动画的ViewGroup,使用全屏的最方便)中。这样我们就完全不用担心遮挡的问题了。但是新的问题产生了,View的内容很容易复制,但是他的位置如何设置呢。显然,我们的目标就是让这两个View重合,但是由于它们不在一个ViewGroup中,所以不能单纯的设置相同的相对位置。在这里,介绍一个简单的方法。


Android动画被父View遮挡的解决办法。_第1张图片
 如图所示,假设红色为手机屏幕。黄色为我们的目标View。而他的父ViewGroup蓝色框的大小不足以让他显示动画。我们需要将目标放入黑色边框的ViewGroup中才行,这时我们只需要首先使用VIew.getLocationOnScreen()方法获取到黄色框相对于屏幕的位置。然后在获取黑色边框相对屏幕的位置。这时我们将黄色View从蓝色框中取出(复制一个黄色View副本也可以),放入黑色框中,这里他相对父组件(黑色边框)的位置就是刚刚获取的黄色相对屏幕位置—黑色相对屏幕位置。这时,我们遮挡的问题就都解决了。语文功底不好,描述有点混乱,但应该很容易理解。

     这里要注意一点,如果在Activity启动时就要展示这种动画,或者通过这种方式想长时间放一个View副本在这个位置上用于显示动画。那么不要在onCreate中获取目标View的位置,这是获取不到的(此时还没有进行layout,View还没有绘制)。我们可以再onCreate中创建相关对象,如View,LayoutParams等。但是位置的获取要放在onWindowFocusChanged()中,否则获取的都是0,没有意义。

下面提供一些简单代码:

public class MainActivity extends Activity implements OnClickListener{
	private View mTargetView;        //目标View
	private View mCopyView;          //复制的View
	private ViewGroup mParentView;     //父View
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		.........        //一些View的获取与设置  省略
		mCopyView = new View(this);      //新建副本View
		mCopyView.setBackgroundColor(Color.RED);  
		RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(0, 0);	 //建立layout属性对象	
		mParentView.addView(mCopyView , params);    //加入父View中
	}
	
	@Override
	public void onWindowFocusChanged(boolean hasFocus) {
		super.onWindowFocusChanged(hasFocus);
		if(hasFocus){
			int[] location = new int[2];
			int[] location_L = new int[2];
			mTargetView.getLocationOnScreen(location);  //获取目标View的相对屏幕位置
			mParentView.getLocationOnScreen(location_L);     //获取父View相对屏幕位置                        
			RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)mCopyView.getLayoutParams();
			params.leftMargin = location[0] - location_L[0];   
			params.topMargin = location[1] - location_L[1];   //给副本View设置位置,与目标View重合
                         .......    //这里还需要设置大小等属性,省略
		}
	}

	@Override
	public void onClick(View v) {	
		mCopyView.startAnimation("动画");
	}	
}

  

你可能感兴趣的:(Android知识总结)