app引導頁(背景圖片切換加各個頁面動畫效果),

來源:互聯網
上載者:User

app引導頁(背景圖片切換加各個頁面動畫效果),

前言:不知不覺中又加班到了10點半,整個啟動頁面做了一天多的時間,一共有三個頁面,每個頁面都有動畫效果,動畫效果調試起來麻煩,既要跟ios統一,又要匹配各種不同的手機,然後產品經理還有可能在中途改需求,程式員各種苦逼有木有,在這個過程中也學到了蠻多東西的,所以寫一篇部落格跟大家分享一下.


先看:




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<LauncherBaseFragment> list = new ArrayList<LauncherBaseFragment>();private BaseFragmentAdapter adapter;private ImageView[] tips;private int currentSelect; @Overrideprotected 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() {@Overridepublic void onPageSelected(int index) {setImageBackground(index);//改變點點點的轉場效果LauncherBaseFragment fragment=list.get(index);list.get(currentSelect).stopAnimation();//停止前一個頁面的動畫fragment.startAnimation();//開啟當前頁面的動畫currentSelect=index;}@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {}@Overridepublic 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);}@Overrideprotected 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

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <com.example.view.GuideViewPager        android:id="@+id/viewpager_launcher"        android:layout_width="match_parent"        android:layout_height="match_parent" />    <RelativeLayout        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:orientation="vertical" >        <LinearLayout            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" />    </RelativeLayout></RelativeLayout>

4.ViewPager適配器

/** * Viewpager適配器 * @author apple * */public class BaseFragmentAdapter extends FragmentStatePagerAdapter {private List<LauncherBaseFragment>list;public BaseFragmentAdapter(FragmentManager fm, List<LauncherBaseFragment> list) {super(fm);this.list = list;}public BaseFragmentAdapter(FragmentManager fm) {super(fm);}@Overridepublic Fragment getItem(int arg0) {return list.get(arg0);}@Overridepublic 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滑動時候給這個變數賦值)@Overridepublic 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() {@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic 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() {@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationRepeat(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {//透明度動畫結束隱藏圖片ivReward.setVisibility(View.GONE);}});                }            });}}@Overridepublic void onAnimationRepeat(Animation animation) {}});}@Overridepublic void stopAnimation(){started=false;//結束動畫時標示符設定為falseivGold.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;//是否開啟動畫@Overridepublic 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秒之後開啟喜歡視頻動畫@Overridepublic 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;    @Overridepublic 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);    } @Overridepublic void onClick(View v) {//Intent intent = new Intent();//intent.setClass(getActivity(),MainActivity.class);//startActivity(intent);//getActivity().finish();}@Overridepublic void startAnimation() {playHeartbeatAnimation();}@Overridepublic void stopAnimation() {}}


最後總結:以上就是三個引導頁的核心代碼了,還有一些布局檔案,動畫效果的布局檔案我就不一一貼出來的,大家可以去下載我的源碼,在這個過程中碰到的幾個大的問題說明一下.

1.viewpager切換的時候要結束上個fragment的動畫   我是通過boolean變數去控制的

2.背景圖片移動的效果    之前自己走了很多彎路,後面在網上找了一個demo拿過來用了.因為大家都有開源精神所以這裡省了很多功夫

3.圖片放大縮小以前居然不知道一個xml動畫布局就能搞定.之前一直想辦法用兩個動畫實現


看看時間一篇部落格寫了一個半小時,都12點了,辦公室一個人敲打著鍵盤,記錄著這兩天做過的東西,才發現這也是一件很愜意的事情。。。。閃人。。。回家.


點擊下載源碼

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.