Android控件ViewPager實(shí)現(xiàn)帶有動(dòng)畫的引導(dǎo)頁(yè)
ViewPager實(shí)現(xiàn)帶有動(dòng)畫的引導(dǎo)頁(yè),供大家參考,具體內(nèi)容如下
好了,又到我們學(xué)習(xí)基礎(chǔ)控件的時(shí)候了,其實(shí)引導(dǎo)頁(yè)很簡(jiǎn)單,就是五張圖片而已
一、ViewPager實(shí)現(xiàn)傳統(tǒng)的引導(dǎo)頁(yè)
傳統(tǒng)的ViewPager實(shí)現(xiàn)引導(dǎo)頁(yè)和ListView是一樣道理的,只是把ListView的Item換成圖片,把BaseAdapter換成PagerAdapter,我們先來(lái)看下傳統(tǒng)引導(dǎo)頁(yè)的效果圖

步驟一:編寫xml文件
既然用到的是ViewPager,那么xml文件就必須要有ViewPager,細(xì)心的你,可能會(huì)發(fā)現(xiàn)最后一頁(yè)還有個(gè)按鈕的出現(xiàn),沒(méi)錯(cuò),xml文件中也要有個(gè)按鈕
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v4.view.ViewPager android:id="@+id/vp_guide" android:layout_width="match_parent" android:layout_height="match_parent" /> <Button android:id="@+id/bt_main" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerInParent="true" android:layout_marginBottom="50dp" android:background="@color/colorPrimary" android:padding="6dp" android:text="立即開(kāi)啟" android:textColor="#fff" android:textSize="16dp" android:visibility="gone" /> </RelativeLayout>
步驟二:編寫Adapter
開(kāi)頭也說(shuō)了,Viewpager其實(shí)就和ListView一樣的,需要一個(gè)Adapter,那么就從Adapter入手。Google提供了一個(gè)專門適配ViewPager的Adapter——PagerAdapter
public class GuideAdapter extends PagerAdapter {
private List<View> views;
private Context context;
public GuideAdapter(List<View> views, Context context) {
this.context = context;
this.views = views;
}
public Object instantiateItem(View container, int position) {
((ViewPager) container).addView(views.get(position));
return views.get(position);
}
public void destroyItem(View container, int position, Object object) {
((ViewPager) container).removeView(views.get(position));
}
public int getCount() {
return views.size();
}
public boolean isViewFromObject(View arg0, Object arg1) {
return (arg0 == arg1);
}
}
基本ViewPager的Adapter都是這么寫的,就是往ViewPager中添加List傳過(guò)來(lái)的View和刪除List傳過(guò)來(lái)的View,可以說(shuō)是每個(gè)ViewPager的模板
步驟三:編寫Activity
我們找到對(duì)應(yīng)的ViewPager,然后設(shè)置Adapter,代碼中的initViews、initListener、initData是按順序執(zhí)行下去的,這段代碼不難,很容易看懂
public class GuideActivity extends BaseActivity implements ViewPager.OnPageChangeListener {
private ViewPager vp_guide;
private int[] imgId = {R.drawable.guide_center_1, R.drawable.guide_center_2, R.drawable.guide_center_3,
R.drawable.guide_center_4, R.drawable.guide_center_5};
private List<View> mImageViews;
private GuideAdapter adapter;
private Button bt_main;
@Override
public void initViews() {
setContentView(R.layout.activity_guide);
vp_guide = (ViewPager) findViewById(R.id.vp_guide);
bt_main = (Button) findViewById(R.id.bt_main);
}
@Override
public void initListener() {
bt_main.setOnClickListener(this);
vp_guide.setOnPageChangeListener(this);
}
@Override
public void initData() {
//初始化引導(dǎo)資源
mImageViews = new ArrayList<>();
for (int i = 0; i < imgId.length; i++) {
ImageView imageView = new ImageView(this);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setImageResource(imgId[i]);
mImageViews.add(imageView);
}
//設(shè)置引導(dǎo)頁(yè)
adapter = new GuideAdapter(mImageViews, this);
vp_guide.setAdapter(adapter);
}
@Override
public void processClick(View v) {
switch (v.getId()) {
//按鈕點(diǎn)擊事件,跳轉(zhuǎn)到主頁(yè)面
case R.id.bt_main:
Intent intent = new Intent(GuideActivity.this, MainActivity.class);
startActivity(intent);
finish();
break;
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (position == imgId.length - 1) {
//最后一個(gè),實(shí)現(xiàn)動(dòng)畫浮現(xiàn)
bt_main.setVisibility(View.VISIBLE);
AlphaAnimation aa = new AlphaAnimation(0, 1f);
aa.setDuration(1000);
bt_main.startAnimation(aa);
} else {
bt_main.setVisibility(View.GONE);
}
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
}
細(xì)心的你可能也發(fā)現(xiàn)了該引導(dǎo)頁(yè)是沒(méi)有狀態(tài)欄的,所以我們需要設(shè)置其主題為狀態(tài)欄透明
<activity android:name=".Activity.GuideActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen"/>
特別注意:這里需要注意的是圖片的大小問(wèn)題,如果圖片高清太大,可能會(huì)出現(xiàn)內(nèi)存溢出的錯(cuò)誤。
二、ViewPager實(shí)現(xiàn)帶有動(dòng)畫的引導(dǎo)頁(yè)
帶有動(dòng)畫的引導(dǎo)頁(yè)編寫步驟和傳統(tǒng)是一模一樣的,只不過(guò)給ViewPager設(shè)置一個(gè)動(dòng)畫。Google提供ViewPager.setPageTransformer(boolean reverseDrawingOrder, PageTransformer transformer)方法來(lái)設(shè)置引導(dǎo)頁(yè)的切換效果,這里先看Google提供的切換Demo

步驟一:編寫PageTransformer
從上面效果看出,只是在引導(dǎo)頁(yè)之間添加了一個(gè)動(dòng)畫而已,而Google提供的PageTransformer就可以對(duì)當(dāng)前位置的引導(dǎo)頁(yè)進(jìn)行操作,比如:設(shè)置透明度的變化,設(shè)置縮放的變化,就能實(shí)現(xiàn)切換的動(dòng)畫效果
public class DepthPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.75f;
@Override
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
if (position < -1) {
view.setAlpha(0);
} else if (position <= 0) {
view.setAlpha(1);
view.setTranslationX(0);
view.setScaleX(1);
view.setScaleY(1);
} else if (position <= 1) {
view.setAlpha(1 - position);
view.setTranslationX(pageWidth * -position);
float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else {
view.setAlpha(0);
}
}
}
步驟二:分析PageTransformer
從上面的代碼中,可以知道在ViewPager滑動(dòng)的時(shí)候,會(huì)觸發(fā)transformPage這個(gè)方法,并且會(huì)將當(dāng)前的position和View傳遞過(guò)來(lái),下面就是我們的對(duì)View的操作
① position
position < -1(即-無(wú)窮到-1):讓引導(dǎo)頁(yè)消失,透明度為0
position <= 0(即-1到0):讓引導(dǎo)頁(yè)出現(xiàn)
position <= 1(即0到1):讓引導(dǎo)頁(yè)根據(jù)position做動(dòng)畫
剩下else(即1到無(wú)窮):讓引導(dǎo)頁(yè)消失,透明度為0
② 圖解position

原諒我畫圖不好看,不生動(dòng),如果還不理解的話可以自己打印Log信息,把View和Position都打印出來(lái)幫助理解
步驟三:使用PageTransformer
使用PageTransformer非常簡(jiǎn)單,只要通過(guò)ViewPager設(shè)置即可
vp_guide.setPageTransformer(true, new DepthPageTransformer());
三、其他動(dòng)畫的引導(dǎo)頁(yè)的參考
Google還為我們提供了另一個(gè)動(dòng)畫效果,看效果圖

實(shí)現(xiàn)步驟其實(shí)和上面的步驟是一樣的,具體我們來(lái)看PageTransformer的編寫
public class ZoomOutPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.85f;
private static final float MIN_ALPHA = 0.5f;
@SuppressLint("NewApi")
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
int pageHeight = view.getHeight();
if (position < -1) {
view.setAlpha(0);
} else if (position <= 1) {
float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
float vertMargin = pageHeight * (1 - scaleFactor) / 2;
float horzMargin = pageWidth * (1 - scaleFactor) / 2;
if (position < 0) {
view.setTranslationX(horzMargin - vertMargin / 2);
} else {
view.setTranslationX(-horzMargin + vertMargin / 2);
}
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
view.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA));
} else {
view.setAlpha(0);
}
}
}
這里的原理就不分析了,和上面是一樣的,只不過(guò)操作不同而已。除了Google提供的Demo之外,我們可以模仿谷歌的Demo,編寫出我們自己的動(dòng)畫效果
public class RotateDownPageTransformer implements ViewPager.PageTransformer {
private static final float ROT_MAX = 20.0f;
private float mRot;
public void transformPage(View view, float position) {
if (position < -1) {
ViewHelper.setRotation(view, 0);
} else if (position <= 1) {
//[-1,1]
mRot = (ROT_MAX * position);
ViewHelper.setPivotX(view, view.getMeasuredWidth() * 0.5f);
ViewHelper.setPivotY(view, view.getMeasuredHeight());
ViewHelper.setRotation(view, mRot);
} else {
ViewHelper.setRotation(view, 0);
}
}
}
效果如圖

好了,今天基礎(chǔ)控件就到這里了,如果不懂的話可以自己實(shí)踐一下,然后用紙筆思考思考,你就會(huì)有收獲的。我也是通過(guò)博客學(xué)習(xí)別人的博客,然后通過(guò)自己的方式,將學(xué)習(xí)的內(nèi)容寫出來(lái)。我們一起加油,后來(lái)者們
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android使用ViewPager實(shí)現(xiàn)啟動(dòng)引導(dǎo)頁(yè)
- Android自定義引導(dǎo)玩轉(zhuǎn)ViewPager的方法詳解
- Android開(kāi)發(fā)實(shí)戰(zhàn)之漂亮的ViewPager引導(dǎo)頁(yè)
- Android開(kāi)發(fā)實(shí)現(xiàn)的ViewPager引導(dǎo)頁(yè)功能(動(dòng)態(tài)加載指示器)詳解
- ViewPager實(shí)現(xiàn)漂亮的引導(dǎo)頁(yè)
- ViewPager實(shí)現(xiàn)帶引導(dǎo)小圓點(diǎn)與自動(dòng)跳轉(zhuǎn)的引導(dǎo)界面
- Android利用ViewPager實(shí)現(xiàn)用戶引導(dǎo)界面效果的方法
- ViewPager打造輪播圖Banner/引導(dǎo)頁(yè)Guide
- Android使用ViewPager完成app引導(dǎo)頁(yè)
- ViewPager實(shí)現(xiàn)輪播圖引導(dǎo)頁(yè)
相關(guān)文章
Android8.1 源碼修改之插入SIM卡默認(rèn)啟用Volte功能
這篇文章主要介紹了Android8.1 源碼修改之插入SIM卡默認(rèn)啟用Volte功能,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-05-05
Android Room數(shù)據(jù)庫(kù)容易遇到的問(wèn)題以及解決方法
這篇文章給大家介紹了我們?cè)贏ndroid Room數(shù)據(jù)庫(kù)容易遇到的坑以及解決方法,文中有詳細(xì)的代碼示例供我們參考,具有一定的參考價(jià)值,需要的朋友可以參考下2023-09-09
Android開(kāi)發(fā)解決popupWindow重疊報(bào)錯(cuò)問(wèn)題
今天小編就為大家分享一篇關(guān)于Android開(kāi)發(fā)解決popupWindow重疊報(bào)錯(cuò)問(wèn)題的文章,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-10-10
另外兩種Android沉浸式狀態(tài)欄實(shí)現(xiàn)思路
這篇文章主要為大家介紹了另外兩種Android沉浸式狀態(tài)欄實(shí)現(xiàn)思路,android5.0及以后版本都支持給狀態(tài)欄著色,而目前android主流版本還是4.4,想要深入了解的朋友可以參考一下2016-01-01
Android實(shí)現(xiàn)波浪線效果(xml bitmap)
這篇文章主要介紹了Android xml bitmap實(shí)現(xiàn)波浪線效果,制作過(guò)程簡(jiǎn)單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-01-01
不依賴于Activity的Android全局懸浮窗的實(shí)現(xiàn)
在Android應(yīng)用開(kāi)發(fā)中,經(jīng)常要遇到做全局懸浮窗的效果,本文的內(nèi)容主要是如何不依賴于Activity的全局懸浮窗的實(shí)現(xiàn)及原理,有需要的可以參考。2016-07-07
Android實(shí)現(xiàn)計(jì)步傳感器功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)計(jì)步傳感器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
深入分析Android ViewStub的應(yīng)用詳解
本篇文章是對(duì)Android ViewStub的應(yīng)用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05

