編輯:關於Android編程
先看效果圖:
1.顯示三個頁面的Activity 用view pager去加載三個fragment實現,控制點點點的切換,監聽view pager的切換,控制fragment動畫的開始跟結束,重寫了view pager,實現了背景圖片的移動效果.
/** *主Activity *@authoransen *@createtime2015-08-07 */ publicclassKaKaLauncherActivityextendsFragmentActivity{ privateGuideViewPagervPager; privateListlist=newArrayList(); privateBaseFragmentAdapteradapter; privateImageView[]tips; privateintcurrentSelect; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_luancher_main); //初始化點點點控件 ViewGroupgroup=(ViewGroup)findViewById(R.id.viewGroup); tips=newImageView[3]; for(inti=0;i ImageViewimageView=newImageView(this); imageView.setLayoutParams(newLayoutParams(10,10)); if(i==0){ imageView.setBackgroundResource(R.drawable.page_indicator_focused); }else{ imageView.setBackgroundResource(R.drawable.page_indicator_unfocused); } tips[i]=imageView; LinearLayout.LayoutParamslayoutParams=newLinearLayout.LayoutParams(newViewGroup.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中 */ RewardLauncherFragmentrewardFragment=newRewardLauncherFragment(); PrivateMessageLauncherFragmentprivateFragment=newPrivateMessageLauncherFragment(); StereoscopicLauncherFragmentstereoscopicFragment=newStereoscopicLauncherFragment(); list.add(rewardFragment); list.add(privateFragment); list.add(stereoscopicFragment); adapter=newBaseFragmentAdapter(getSupportFragmentManager(),list); vPager.setAdapter(adapter); vPager.setOffscreenPageLimit(2); vPager.setCurrentItem(0); vPager.setOnPageChangeListener(changeListener); } /** *監聽viewpager的移動 */ OnPageChangeListenerchangeListener=newOnPageChangeListener(){ @Override publicvoidonPageSelected(intindex){ setImageBackground(index);//改變點點點的切換效果 LauncherBaseFragmentfragment=list.get(index); list.get(currentSelect).stopAnimation();//停止前一個頁面的動畫 fragment.startAnimation();//開啟當前頁面的動畫 currentSelect=index; } @Override publicvoidonPageScrolled(intarg0,floatarg1,intarg2){} @Override publicvoidonPageScrollStateChanged(intarg0){} }; /** *改變點點點的切換效果 *@paramselectItems */ privatevoidsetImageBackground(intselectItems){ for(inti=0;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主要做一個切換背景的功能 *@authoransen *@createtime2015-08-07 */ publicclassGuideViewPagerextendsViewPager{ privateBitmapbg; privatePaintb=newPaint(1); publicGuideViewPager(Contextcontext){ super(context); } publicGuideViewPager(Contextcontext,AttributeSetattrs){ super(context,attrs); } @Override protectedvoiddispatchDraw(Canvascanvas){ if(this.bg!=null){ intwidth=this.bg.getWidth(); intheight=this.bg.getHeight(); intcount=getAdapter().getCount(); intx=getScrollX(); //子View中背景圖片需要顯示的寬度,放大背景圖或縮小背景圖。 intn=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個像素時,背景圖片滑動的寬度。 *背景圖片滑動的寬度的寬度可以理解為背景圖片滑動到達的位置。 */ intw=x*((width-n)/(count-1))/getWidth(); canvas.drawBitmap(this.bg,newRect(w,0,n+w,height),newRect(x,0,x+getWidth(),getHeight()),this.b); } super.dispatchDraw(canvas); } publicvoidsetBackGroud(BitmapparamBitmap){ this.bg=paramBitmap; this.b.setFilterBitmap(true); } }
3.主體布局文件 上面放一個自定義的viewpager 下面放一個顯示點點的RelativeLayout
android:layout_width="match_parent" android:layout_height="match_parent"> android:id="@+id/viewpager_launcher" android:layout_width="match_parent" android:layout_height="match_parent"/> android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical"> android:id="@+id/viewGroup" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginBottom="30dp" android:gravity="center_horizontal" android:orientation="horizontal"/>
4.ViewPager適配器
/** *Viewpager適配器 *@authorapple * */ publicclassBaseFragmentAdapterextendsFragmentStatePagerAdapter{ privateListlist; publicBaseFragmentAdapter(FragmentManagerfm,Listlist){ super(fm); this.list=list; } publicBaseFragmentAdapter(FragmentManagerfm){ super(fm); } @Override publicFragmentgetItem(intarg0){ returnlist.get(arg0); } @Override publicintgetCount(){ returnlist.size(); } }
5.Fragment抽象類 有兩個抽象方法,開啟動畫跟停止動畫 所有的Fragment都繼承這個類 Viewpager切換的時候可以更好的控制每個Fragment開啟動畫,結束動畫
/** *Fragment抽象類 *@authoransen * */ publicabstractclassLauncherBaseFragmentextendsFragment{ publicabstractvoidstartAnimation(); publicabstractvoidstopAnimation(); }
6.打賞頁Fragment 三個動畫效果 硬幣向下移動動畫+打賞圖片縮放動畫+改變打賞圖片透明度然後隱藏圖片
/** *打賞頁面 *@authoransen *@createtime2015-08-07 */ publicclassRewardLauncherFragmentextendsLauncherBaseFragment{ privateImageViewivReward; privateImageViewivGold; privateBitmapgoldBitmap; privatebooleanstarted;//是否開啟動畫(ViewPage滑動時候給這個變量賦值) @Override publicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer,BundlesavedInstanceState){ ViewrooView=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(); returnrooView; } publicvoidstartAnimation(){ started=true; //向下移動動畫硬幣的高度*2+80 TranslateAnimationtranslateAnimation=newTranslateAnimation(0,0,0,goldBitmap.getHeight()*2+80); translateAnimation.setDuration(500); translateAnimation.setFillAfter(true); ivGold.startAnimation(translateAnimation); translateAnimation.setAnimationListener(newAnimationListener(){ @Override publicvoidonAnimationStart(Animationanimation){} @Override publicvoidonAnimationEnd(Animationanimation){ if(started){ ivReward.setVisibility(View.VISIBLE); //硬幣移動動畫結束開啟縮放動畫 Animationanim=AnimationUtils.loadAnimation(getActivity(),R.anim.reward_launcher); ivReward.startAnimation(anim); anim.setAnimationListener(newAnimationListener(){ @Override publicvoidonAnimationStart(Animationanimation){} @Override publicvoidonAnimationRepeat(Animationanimation){} @Override publicvoidonAnimationEnd(Animationanimation){ //縮放動畫結束開啟改變透明度動畫 AlphaAnimationalphaAnimation=newAlphaAnimation(1,0); alphaAnimation.setDuration(1000); ivReward.startAnimation(alphaAnimation); alphaAnimation.setAnimationListener(newAnimationListener(){ @Override publicvoidonAnimationStart(Animationanimation){} @Override publicvoidonAnimationRepeat(Animationanimation){} @Override publicvoidonAnimationEnd(Animationanimation){ //透明度動畫結束隱藏圖片 ivReward.setVisibility(View.GONE); } }); } }); } } @Override publicvoidonAnimationRepeat(Animationanimation){} }); } @Override publicvoidstopAnimation(){ started=false;//結束動畫時標示符設置為false ivGold.clearAnimation();//清空view上的動畫 } }
7.私信頁面 四個動畫效果 並且四個動畫都相同,其實只要我們實現了一個,其他的基本都很容易了. 依次實現四個圖片的放大然後還原
/** *私信 *@authoransen */ publicclassPrivateMessageLauncherFragmentextendsLauncherBaseFragment{ privateImageViewivLikeVideo,ivThinkReward,ivThisWeek,ivWatchMovie; privateAnimationlikeAnimation,thinkAnimation,watchAnimation,thisWeekAnimation; privatebooleanstarted;//是否開啟動畫 @Override publicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer,BundlesavedInstanceState){ ViewrooView=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); returnrooView; } publicvoidstopAnimation(){ //動畫開啟標示符設置成false started=false; /** *清空所有控件上的動畫 */ ivLikeVideo.clearAnimation(); ivThinkReward.clearAnimation(); ivWatchMovie.clearAnimation(); ivThisWeek.clearAnimation(); } publicvoidstartAnimation(){ started=true; /** *每次開啟動畫前先隱藏控件 */ ivLikeVideo.setVisibility(View.GONE); ivThinkReward.setVisibility(View.GONE); ivWatchMovie.setVisibility(View.GONE); ivThisWeek.setVisibility(View.GONE); newHandler().postDelayed(newRunnable(){//延時0.5秒之後開啟喜歡視頻動畫 @Override publicvoidrun(){ if(started) likeVideoAnimation(); } },500); } /** *好喜歡你的視頻 */ privatevoidlikeVideoAnimation(){ ivLikeVideo.setVisibility(View.VISIBLE); likeAnimation=AnimationUtils.loadAnimation(getActivity(),R.anim.private_message_launcher); ivLikeVideo.startAnimation(likeAnimation);//開啟動畫 likeAnimation.setAnimationListener(newAnimationListener(){ @Override publicvoidonAnimationStart(Animationanimation){} @Override publicvoidonAnimationRepeat(Animationanimation){} @Override publicvoidonAnimationEnd(Animationanimation){//監聽動畫結束 if(started) thinkReward(); } }); } /** *謝謝你的打賞 */ privatevoidthinkReward(){ ivThinkReward.setVisibility(View.VISIBLE); thinkAnimation=AnimationUtils.loadAnimation(getActivity(),R.anim.private_message_launcher); ivThinkReward.startAnimation(thinkAnimation); thinkAnimation.setAnimationListener(newAnimationListener(){ @Override publicvoidonAnimationStart(Animationanimation){} @Override publicvoidonAnimationRepeat(Animationanimation){} @Override publicvoidonAnimationEnd(Animationanimation){ if(started) watchMovie(); } }); } /** *一起看個電影呗 */ privatevoidwatchMovie(){ ivWatchMovie.setVisibility(View.VISIBLE); watchAnimation=AnimationUtils.loadAnimation(getActivity(),R.anim.private_message_launcher); ivWatchMovie.startAnimation(watchAnimation); watchAnimation.setAnimationListener(newAnimationListener(){ @Override publicvoidonAnimationStart(Animationanimation){} @Override publicvoidonAnimationRepeat(Animationanimation){} @Override publicvoidonAnimationEnd(Animationanimation){ if(started) thisWeek(); } }); } /** *好啊這周末有空 */ privatevoidthisWeek(){ ivThisWeek.setVisibility(View.VISIBLE); thisWeekAnimation=AnimationUtils.loadAnimation(getActivity(),R.anim.private_message_launcher); ivThisWeek.startAnimation(thisWeekAnimation); } }
8.最後一個引導頁 就兩個動畫 圖片的放大跟縮小,其實用xml布局的話一個動畫就能搞定,跟私信頁面的動畫差不多.小伙伴寫的代碼.這裡換了一種方式.代碼比較多.
/** *最後一個 *@authorapple */ publicclassStereoscopicLauncherFragmentextendsLauncherBaseFragmentimplementsOnClickListener{ privatestaticfinalfloatZOOM_MAX=1.3f; privatestaticfinalfloatZOOM_MIN=1.0f; privateImageViewimgView_immediate_experience; @Override publicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer,BundlesavedInstanceState){ ViewrooView=inflater.inflate(R.layout.fragment_stereoscopic_launcher,null); imgView_immediate_experience=(ImageView)rooView.findViewById(R.id.imgView_immediate_experience); imgView_immediate_experience.setOnClickListener(this); returnrooView; } publicvoidplayHeartbeatAnimation(){ /** *放大動畫 */ AnimationSetanimationSet=newAnimationSet(true); animationSet.addAnimation(newScaleAnimation(ZOOM_MIN,ZOOM_MAX,ZOOM_MIN,ZOOM_MAX,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f)); animationSet.addAnimation(newAlphaAnimation(1.0f,0.8f)); animationSet.setDuration(500); animationSet.setInterpolator(newAccelerateInterpolator()); animationSet.setFillAfter(true); animationSet.setAnimationListener(newAnimationListener(){ @Override publicvoidonAnimationStart(Animationanimation){ } @Override publicvoidonAnimationRepeat(Animationanimation){ } @Override publicvoidonAnimationEnd(Animationanimation){ /** *縮小動畫 */ AnimationSetanimationSet=newAnimationSet(true); animationSet.addAnimation(newScaleAnimation(ZOOM_MAX,ZOOM_MIN,ZOOM_MAX,ZOOM_MIN,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f)); animationSet.addAnimation(newAlphaAnimation(0.8f,1.0f)); animationSet.setDuration(600); animationSet.setInterpolator(newDecelerateInterpolator()); animationSet.setFillAfter(false); //實現心跳的View imgView_immediate_experience.startAnimation(animationSet); } }); //實現心跳的View imgView_immediate_experience.startAnimation(animationSet); } @Override publicvoidonClick(Viewv){ //Intentintent=newIntent(); //intent.setClass(getActivity(),MainActivity.class); //startActivity(intent); //getActivity().finish(); } @Override publicvoidstartAnimation(){ playHeartbeatAnimation(); } @Override publicvoidstopAnimation(){ } }
最後總結:以上就是三個引導頁的核心代碼了,還有一些布局文件,動畫效果的布局文件我就不一一貼出來的,大家可以去下載我的源碼,在這個過程中碰到的幾個大的問題說明一下.
1.viewpager切換的時候要結束上個fragment的動畫 我是通過boolean變量去控制的
2.背景圖片移動的效果 之前自己走了很多彎路,後面在網上找了一個demo拿過來用了.因為大家都有開源精神所以這裡省了很多功夫
3.圖片放大縮小以前居然不知道一個xml動畫布局就能搞定.之前一直想辦法用兩個動畫實現
看看時間一篇博客寫了一個半小時,都12點了,辦公室一個人敲打著鍵盤,記錄著這兩天做過的東西,才發現這也是一件很惬意的事情。。。。閃人。。。回家.
推薦下自己創建的android QQ群:202928390歡迎大家的加入.
點擊下載源碼
如果你想第一時間看我們的後期文章,掃碼關注公眾號,每個周末都會推送Android開發實戰教程一篇,其余時間我們會推出一些互聯網行業新聞,你還等什麼,趕快關注吧,既能學到技術,還能長逼格,出任ceo,贏取白富美。。。。。
本文檔介紹了Android中執行基本任務NFC。它說明了如何在NDEF消息的形式發送和接收數據的NFC並介紹了支持這些功能的Andr??oid框架的API。對於更高級的主
android中的json的讀取1.讀取Json文件中的json內容首先在將json文件放在目錄assets下:test.json {programmers:[
最近在研究AMS代碼遇到一個問題,在函數startActivityUncheckedLocked中 Slog.d("DDY", "!!
1.Handler是什麼?Handler是Android給我們提供的一套更新UI的機制,也封裝了一套消息處理的機制,可以發送消息,也可以通過它處理消息。eg:Handle