Android之app引导页(背景图片切换加各个页面动画效果)
发布日期:2021-06-29 13:59:21 浏览次数:2 分类:技术文章

本文共 14350 字,大约阅读时间需要 47 分钟。

转载:http://blog.csdn.net/lowprofile_coding/article/details/48037095

先看效果图:

1.显示三个页面的Activity  用view pager去加载三个fragment实现,控制点点点的切换,监听view pager的切换,控制fragment动画的开始跟结束,重写了view pager,实现了背景图片的移动效果.

/** * 主Activity * @author ansen * @create time 2015-08-07 */public class KaKaLauncherActivity extends FragmentActivity {	private GuideViewPager vPager;	private List
list = new ArrayList
(); private BaseFragmentAdapter adapter; private ImageView[] tips; private int currentSelect; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_luancher_main); //初始化点点点控件 ViewGroup group = (ViewGroup)findViewById(R.id.viewGroup); tips = new ImageView[3]; for (int i = 0; i < tips.length; i++) { ImageView imageView = new ImageView(this); imageView.setLayoutParams(new LayoutParams(10, 10)); if (i == 0) { imageView.setBackgroundResource(R.drawable.page_indicator_focused); } else { imageView.setBackgroundResource(R.drawable.page_indicator_unfocused); } tips[i]=imageView; LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT)); layoutParams.leftMargin = 20;//设置点点点view的左边距 layoutParams.rightMargin = 20;//设置点点点view的右边距 group.addView(imageView,layoutParams); } //获取自定义viewpager 然后设置背景图片 vPager = (GuideViewPager) findViewById(R.id.viewpager_launcher); vPager.setBackGroud(BitmapFactory.decodeResource(getResources(),R.drawable.bg_kaka_launcher)); /** * 初始化三个fragment 并且添加到list中 */ RewardLauncherFragment rewardFragment = new RewardLauncherFragment(); PrivateMessageLauncherFragment privateFragment = new PrivateMessageLauncherFragment(); StereoscopicLauncherFragment stereoscopicFragment = new StereoscopicLauncherFragment(); list.add(rewardFragment); list.add(privateFragment); list.add(stereoscopicFragment); adapter = new BaseFragmentAdapter(getSupportFragmentManager(),list); vPager.setAdapter(adapter); vPager.setOffscreenPageLimit(2); vPager.setCurrentItem(0); vPager.setOnPageChangeListener(changeListener); } /** * 监听viewpager的移动 */ OnPageChangeListener changeListener=new OnPageChangeListener() { @Override public void onPageSelected(int index) { setImageBackground(index);//改变点点点的切换效果 LauncherBaseFragment fragment=list.get(index); list.get(currentSelect).stopAnimation();//停止前一个页面的动画 fragment.startAnimation();//开启当前页面的动画 currentSelect=index; } @Override public void onPageScrolled(int arg0, float arg1, int arg2) {} @Override public void onPageScrollStateChanged(int arg0) {} }; /** * 改变点点点的切换效果 * @param selectItems */ private void setImageBackground(int selectItems) { for (int i = 0; i < tips.length; i++) { if (i == selectItems) { tips[i].setBackgroundResource(R.drawable.page_indicator_focused); } else { tips[i].setBackgroundResource(R.drawable.page_indicator_unfocused); } } }}
2.重写viewpager   在dispatchDraw方法中控制显示的背景图片区域,

/** * 重写ViewPager  主要做一个切换背景的功能 * @author ansen * @create time 2015-08-07 */public class GuideViewPager extends ViewPager {	private Bitmap bg;	private Paint b = new Paint(1);		public GuideViewPager(Context context) {		super(context);	}	public GuideViewPager(Context context, AttributeSet attrs) {		super(context, attrs);	}	@Override	protected void dispatchDraw(Canvas canvas) {		if (this.bg != null) {			int width = this.bg.getWidth();			int height = this.bg.getHeight();			int count = getAdapter().getCount();			int x = getScrollX();			// 子View中背景图片需要显示的宽度,放大背景图或缩小背景图。			int n = height * getWidth() / getHeight();						/**			 * (width - n) / (count - 1)表示除去显示第一个ViewPager页面用去的背景宽度,剩余的ViewPager需要显示的背景图片的宽度。			 * getWidth()等于ViewPager一个页面的宽度,即手机屏幕宽度。在该计算中可以理解为滑动一个ViewPager页面需要滑动的像素值。			 * ((width - n) / (count - 1)) /getWidth()也就表示ViewPager滑动一个像素时,背景图片滑动的宽度。			 * x * ((width - n) / (count - 1)) /  getWidth()也就表示ViewPager滑动x个像素时,背景图片滑动的宽度。			 * 背景图片滑动的宽度的宽度可以理解为背景图片滑动到达的位置。			 */			int w = x * ((width - n) / (count - 1)) / getWidth();			canvas.drawBitmap(this.bg, new Rect(w, 0, n + w, height), new Rect( x, 0, x + getWidth(), getHeight()), this.b);		}		super.dispatchDraw(canvas);	}		public void setBackGroud(Bitmap paramBitmap) {		this.bg = paramBitmap;		this.b.setFilterBitmap(true);	}}
3.主体布局文件  上面放一个自定义的viewpager  下面放一个显示点点的RelativeLayout

4.ViewPager适配器

/** * Viewpager适配器 * @author apple * */public class BaseFragmentAdapter extends FragmentStatePagerAdapter {	private List
list; public BaseFragmentAdapter(FragmentManager fm, List
list) { super(fm); this.list = list; } public BaseFragmentAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int arg0) { return list.get(arg0); } @Override public int getCount() { return list.size(); }}
5.Fragment抽象类 有两个抽象方法,开启动画跟停止动画  所有的Fragment都继承这个类  Viewpager切换的时候可以更好的控制每个Fragment开启动画,结束动画

/** * Fragment抽象类 * @author ansen *  */public abstract class LauncherBaseFragment extends Fragment{	public abstract void  startAnimation();	public abstract void  stopAnimation();}
6.打赏页Fragment  三个动画效果  硬币向下移动动画+打赏图片缩放动画+改变打赏图片透明度然后隐藏图片

/** * 打赏页面 * @author ansen * @create time 2015-08-07 */public class RewardLauncherFragment extends LauncherBaseFragment{	private ImageView ivReward;	private ImageView ivGold;		private Bitmap goldBitmap;	private boolean started;//是否开启动画(ViewPage滑动时候给这个变量赋值)		@Override	public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {		View rooView=inflater.inflate(R.layout.fragment_reward_launcher, null);		ivGold=(ImageView) rooView.findViewById(R.id.iv_gold);		ivReward=(ImageView) rooView.findViewById(R.id.iv_reward);				//获取硬币的高度		goldBitmap=BitmapFactory.decodeResource(getActivity().getResources(),R.drawable.icon_gold);		startAnimation();		return rooView;	}		public void startAnimation(){		started=true;				//向下移动动画 硬币的高度*2+80   		TranslateAnimation translateAnimation=new TranslateAnimation(0,0,0,goldBitmap.getHeight()*2+80);		translateAnimation.setDuration(500);		translateAnimation.setFillAfter(true);				ivGold.startAnimation(translateAnimation);		translateAnimation.setAnimationListener(new AnimationListener() {			@Override			public void onAnimationStart(Animation animation) {}			@Override			public void onAnimationEnd(Animation animation){				if(started){					ivReward.setVisibility(View.VISIBLE);					//硬币移动动画结束开启缩放动画		            Animation anim=AnimationUtils.loadAnimation(getActivity(),R.anim.reward_launcher);  		            ivReward.startAnimation(anim);		            anim.setAnimationListener(new AnimationListener(){		                @Override  		                public void onAnimationStart(Animation animation) {}  		                @Override  		                public void onAnimationRepeat(Animation animation) {}  		                @Override  		                public void onAnimationEnd(Animation animation) {		                		//缩放动画结束 开启改变透明度动画		                		AlphaAnimation alphaAnimation=new AlphaAnimation(1,0);		                		alphaAnimation.setDuration(1000);		                		ivReward.startAnimation(alphaAnimation);		                		alphaAnimation.setAnimationListener(new AnimationListener() {									@Override									public void onAnimationStart(Animation animation) {}									@Override									public void onAnimationRepeat(Animation animation) {}									@Override									public void onAnimationEnd(Animation animation) {										//透明度动画结束隐藏图片										ivReward.setVisibility(View.GONE);									}							});		                }		            });				}			}			@Override			public void onAnimationRepeat(Animation animation) {}		});	}		@Override	public void stopAnimation(){		started=false;//结束动画时标示符设置为false		ivGold.clearAnimation();//清空view上的动画	}}
7.私信页面   四个动画效果   并且四个动画都相同,其实只要我们实现了一个,其他的基本都很容易了.   依次实现四个图片的放大然后还原

/** * 私信 * @author ansen */public class PrivateMessageLauncherFragment extends LauncherBaseFragment{	private ImageView ivLikeVideo,ivThinkReward,ivThisWeek,ivWatchMovie;		private Animation likeAnimation,thinkAnimation,watchAnimation,thisWeekAnimation;		private boolean started;//是否开启动画		@Override	public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {		View rooView=inflater.inflate(R.layout.fragment_private_message_launcher, null);				ivLikeVideo=(ImageView) rooView.findViewById(R.id.iv_private_message_like_video);		ivThinkReward=(ImageView) rooView.findViewById(R.id.iv_private_message_think_reward);		ivWatchMovie=(ImageView) rooView.findViewById(R.id.iv_private_message_watch_movie);		ivThisWeek=(ImageView) rooView.findViewById(R.id.private_message_this_week);		return rooView;	}		public void stopAnimation(){		//动画开启标示符设置成false   		started=false;		/**		 * 清空所有控件上的动画		 */		ivLikeVideo.clearAnimation();		ivThinkReward.clearAnimation();		ivWatchMovie.clearAnimation();		ivThisWeek.clearAnimation();	}			public void startAnimation(){		started=true;				/**		 * 每次开启动画前先隐藏控件		 */		ivLikeVideo.setVisibility(View.GONE);		ivThinkReward.setVisibility(View.GONE);		ivWatchMovie.setVisibility(View.GONE);		ivThisWeek.setVisibility(View.GONE);				new Handler().postDelayed(new Runnable() {//延时0.5秒之后开启喜欢视频动画			@Override			public void run(){				if(started)					likeVideoAnimation();			}		},500);	}		/**	 * 好喜欢你的视频	 */	private void likeVideoAnimation(){		ivLikeVideo.setVisibility(View.VISIBLE);				likeAnimation = AnimationUtils.loadAnimation(getActivity(),R.anim.private_message_launcher);		ivLikeVideo.startAnimation(likeAnimation);//开启动画		likeAnimation.setAnimationListener(new AnimationListener(){              @Override              public void onAnimationStart(Animation animation) {}              @Override              public void onAnimationRepeat(Animation animation) {}              @Override              public void onAnimationEnd(Animation animation) {//监听动画结束	            	if(started)	            		thinkReward();            }          }); 	}		/**	 * 谢谢你的打赏	 */	private void thinkReward(){		ivThinkReward.setVisibility(View.VISIBLE);		thinkAnimation = AnimationUtils.loadAnimation(getActivity(),R.anim.private_message_launcher);		ivThinkReward.startAnimation(thinkAnimation);		thinkAnimation.setAnimationListener(new AnimationListener(){              @Override              public void onAnimationStart(Animation animation) {}              @Override              public void onAnimationRepeat(Animation animation) {}              @Override              public void onAnimationEnd(Animation animation) {            	if(started)            		watchMovie();            }          }); 	}		/**	 * 一起看个电影呗	 */	private void watchMovie(){		ivWatchMovie.setVisibility(View.VISIBLE);		watchAnimation = AnimationUtils.loadAnimation(getActivity(),R.anim.private_message_launcher);		ivWatchMovie.startAnimation(watchAnimation);		watchAnimation.setAnimationListener(new AnimationListener(){              @Override              public void onAnimationStart(Animation animation) {}              @Override              public void onAnimationRepeat(Animation animation) {}              @Override              public void onAnimationEnd(Animation animation) {            	if(started)            		thisWeek();            }          }); 	}		/**	 * 好啊  这周末有空	 */	private void thisWeek(){		ivThisWeek.setVisibility(View.VISIBLE);		thisWeekAnimation = AnimationUtils.loadAnimation(getActivity(),R.anim.private_message_launcher);  		ivThisWeek.startAnimation(thisWeekAnimation);	}}
8.最后一个引导页  就两个动画  图片的放大跟缩小,其实用xml布局的话一个动画就能搞定,跟私信页面的动画差不多.小伙伴写的代码.这里换了一种方式.代码比较多.

/** * 最后一个 * @author apple */public class StereoscopicLauncherFragment extends LauncherBaseFragment implements OnClickListener{	private static final float ZOOM_MAX = 1.3f;	private static final  float ZOOM_MIN = 1.0f;		private ImageView imgView_immediate_experience;    	@Override	public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {		View rooView=inflater.inflate(R.layout.fragment_stereoscopic_launcher, null);		imgView_immediate_experience=(ImageView) rooView.findViewById(R.id.imgView_immediate_experience);		imgView_immediate_experience.setOnClickListener(this);		return rooView;	}	    public void playHeartbeatAnimation(){    		/**    		 * 放大动画    		 */        AnimationSet animationSet = new AnimationSet(true);		animationSet.addAnimation(new ScaleAnimation(ZOOM_MIN, ZOOM_MAX, ZOOM_MIN, ZOOM_MAX, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f));        animationSet.addAnimation(new AlphaAnimation(1.0f, 0.8f));         animationSet.setDuration(500);        animationSet.setInterpolator(new AccelerateInterpolator());        animationSet.setFillAfter(true);         animationSet.setAnimationListener(new AnimationListener() {            @Override            public void onAnimationStart(Animation animation) {            }             @Override            public void onAnimationRepeat(Animation animation) {            }             @Override            public void onAnimationEnd(Animation animation) {	        		/**	        		 * 缩小动画	        		 */                AnimationSet animationSet = new AnimationSet(true);                animationSet.addAnimation(new ScaleAnimation(ZOOM_MAX, ZOOM_MIN, ZOOM_MAX,ZOOM_MIN, Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF, 0.5f));                animationSet.addAnimation(new AlphaAnimation(0.8f, 1.0f));                animationSet.setDuration(600);                animationSet.setInterpolator(new DecelerateInterpolator());                animationSet.setFillAfter(false);                 // 实现心跳的View                imgView_immediate_experience.startAnimation(animationSet);            }        });         // 实现心跳的View        imgView_immediate_experience.startAnimation(animationSet);    } 	@Override	public void onClick(View v) {//		Intent intent = new Intent();//		intent.setClass(getActivity(),MainActivity.class);//		startActivity(intent);//		getActivity().finish();	}	@Override	public void startAnimation() {		playHeartbeatAnimation();	}	@Override	public void stopAnimation() {			}}

最后总结:以上就是三个引导页的核心代码了,还有一些布局文件,动画效果的布局文件我就不一一贴出来的,大家可以去下载我的源码,在这个过程中碰到的几个大的问题说明一下.

1.viewpager切换的时候要结束上个fragment的动画   我是通过boolean变量去控制的

2.背景图片移动的效果    之前自己走了很多弯路,后面在网上找了一个demo拿过来用了.因为大家都有开源精神所以这里省了很多功夫

3.图片放大缩小以前居然不知道一个xml动画布局就能搞定.之前一直想办法用两个动画实现

转载地址:https://chenyu.blog.csdn.net/article/details/49283289 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:二分查找找下标或者值
下一篇:Android之调用微信登陆、分享、支付

发表评论

最新留言

关注你微信了!
[***.104.42.241]2024年04月06日 16时17分45秒