編輯:關於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 API Guides---NFC Basics
本文檔介紹了Android中執行基本任務NFC。它說明了如何在NDEF消息的形式發送和接收數據的NFC並介紹了支持這些功能的Andr??oid框架的API。對於更高級的主
android中的json二之json的讀寫
android中的json的讀取1.讀取Json文件中的json內容首先在將json文件放在目錄assets下:test.json {programmers:[
探究startActivityForResult在singleTop和singleTask啟動模式討論
最近在研究AMS代碼遇到一個問題,在函數startActivityUncheckedLocked中 Slog.d("DDY", "!!
Android之handler詳解(一)
1.Handler是什麼?Handler是Android給我們提供的一套更新UI的機制,也封裝了一套消息處理的機制,可以發送消息,也可以通過它處理消息。eg:Handle