1. 程式人生 > >使用ViewPager+Fragment製作Material Design(MD)風格的炫酷引導頁

使用ViewPager+Fragment製作Material Design(MD)風格的炫酷引導頁

使用ViewPager+Fragment製作Material Design(MD)風格的炫酷引導頁

我記得之前寫過一篇關於ViewPager+Fragment製作引導頁的Blog。

使用ViewPager+Fragment製作一個簡單的引導頁,外加一個簡易的Indicator圓形指示器

這篇文章實現的效果還不錯,但是肯定比不上今天的這篇文章中最後執行的效果。

讓我們重新使用ViewPager+Fragment,來製作一個Material Design(MD)風格的炫酷引導頁吧。

引導頁,用少量的文字表達出明確的含義,這在引導使用者領域是個很討巧的方法。簡單明瞭的三張圖片,就把APP的主要作用功能全面的展示出來,會給使用者留下一種操作起來一點也不復雜的第一印象,好像只需三步就能輕輕鬆鬆滿足自己的需求。可愛的介面風格也很有針對性的引起了主要客戶群的興趣,為APP整體加分不少。

引導頁面的主要作用是介紹APP的基本功能,根據基礎功能進行操作演示也不失為引導使用者的好方法。將使用方法直接用最簡單的圖示按順序展示在使用者面前,一定能讓使用者最快速的掌握。

首先就是要新增依賴了,在Module的build.gradle檔案中,新增支援庫的依賴。

dependencies {
    ......
    // design
    implementation 'com.android.support:design:28.0.0'
}

然後開始編寫程式碼,步驟如下:

  1. 使用ViewPager + Fragment建立引導頁(FragmentPagerAdapter,Fragment)
  2. 當頁面滑動時,控制背景色的漸變(使用ArgbEvaluator用於更新顏色,在前一個頁面和後一個頁面的顏色之間進行過渡。)
  3. 當App第一次載入時,顯示引導頁(使用SharedPreferences儲存標記)

先看一下引導頁面的佈局檔案activity_pager.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:
app
="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main_content" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/cyan" tools:context=".PagerActivity">
<android.support.v4.view.ViewPager android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="?attr/actionBarSize" /> <View android:layout_width="match_parent" android:layout_height="1dp" android:layout_gravity="bottom" android:layout_marginBottom="?attr/actionBarSize" android:alpha="0.12" android:background="@android:color/white" /> <FrameLayout android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:layout_gravity="bottom" android:paddingStart="@dimen/activity_horizontal_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingEnd="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin"> <Button android:id="@+id/btn_skip" style="@style/Widget.AppCompat.Button.Borderless" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="start|center" android:text="@string/skip" android:textColor="@android:color/white" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:orientation="horizontal"> <ImageView android:id="@+id/image_indicator_zero" android:layout_width="8dp" android:layout_height="8dp" android:layout_marginEnd="@dimen/activity_margin_half" android:layout_marginRight="@dimen/activity_margin_half" android:background="@drawable/indicator_unselected" /> <ImageView android:id="@+id/image_indicator_one" android:layout_width="8dp" android:layout_height="8dp" android:layout_marginEnd="@dimen/activity_margin_half" android:layout_marginRight="@dimen/activity_margin_half" android:background="@drawable/indicator_unselected" /> <ImageView android:id="@+id/image_indicator_two" style="@style/Widget.AppCompat.Button.Borderless" android:layout_width="8dp" android:layout_height="8dp" android:background="@drawable/indicator_unselected" /> </LinearLayout> <Button android:id="@+id/btn_finish" style="@style/Widget.AppCompat.Button.Borderless" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="end|center" android:text="@string/finish" android:textColor="@android:color/white" android:visibility="gone" /> <ImageButton android:id="@+id/btn_next" style="@style/Widget.AppCompat.Button.Borderless" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="end|center" android:padding="@dimen/activity_horizontal_margin" android:src="@drawable/ic_chevron_right_24dp" android:tint="@android:color/white" /> </FrameLayout> </android.support.design.widget.CoordinatorLayout>

然後就是引導頁的Activity檔案

import android.animation.ArgbEvaluator;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;

import com.yunyang.yunyangblogdemo.adapter.GuidePagerAdapter;
import com.yunyang.yunyangblogdemo.utils.Utils;

public class PagerActivity extends AppCompatActivity implements View.OnClickListener {

    private static final String TAG = "yunyang";

    private ViewPager mViewPager;
    private Button btn_skip;
    private ImageView image_indicator_zero;
    private ImageView image_indicator_one;
    private ImageView image_indicator_two;
    private Button btn_finish;
    private ImageButton mNextBtn;

    private GuidePagerAdapter mGuidePagerAdapter;

    private int lastLeftValue = 0;
    private ImageView[] indicators;
    // 當前頁面位置
    private int currentPage = 0;

    // 是否首次進入引導頁的標記
    private boolean isFirstGuide;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            // 沉浸式狀態列
            getWindow().getDecorView().setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
            // 更改狀態列顏色
            getWindow().setStatusBarColor(ContextCompat.getColor(this, R.color.black_trans80));
        }
        setContentView(R.layout.activity_pager);
        // 首次進入App,展示引導頁。
        isFirstGuide = Utils.readSharedSetting(PagerActivity.this, "isGuide", false);
        if (isFirstGuide) {
            gotoMain();
        }
        initView();
        initMDViewPager();
    }

    /**
     * 跳轉首頁
     */
    private void gotoMain() {
        finish();
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
         /*
             注意:
            1、overridePendingTransition方法必須在startActivity()或者finish()方法的後面。
            2、如果引數是0,表示沒有動畫
            public void overridePendingTransition(int enterAnim, int exitAnim) {}
            在A啟動B時:
            enterAnim:是B進入的動畫
            exitAnim:是A退出的動畫
             */
        overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
    }

    private void initMDViewPager() {
        mGuidePagerAdapter = new GuidePagerAdapter(getSupportFragmentManager());
        mNextBtn = (ImageButton) findViewById(R.id.btn_next);
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP)
            mNextBtn.setImageDrawable(
                    Utils.tintMyDrawable(ContextCompat.getDrawable(this, R.drawable.ic_chevron_right_24dp), Color.WHITE)
            );
        indicators = new ImageView[]{
                image_indicator_zero,
                image_indicator_one,
                image_indicator_two
        };
        mViewPager.setAdapter(mGuidePagerAdapter);
        mViewPager.setCurrentItem(currentPage);
        updateIndicators(currentPage);

        final int color1 = ContextCompat.getColor(this, R.color.cyan);
        final int color2 = ContextCompat.getColor(this, R.color.green);
        final int color3 = ContextCompat.getColor(this, R.color.orange);

        final int[] colorList = new int[]{color1, color2, color3};
        // 使用ArgbEvaluator用於更新顏色,在前一個頁面和後一個頁面的顏色之間進行過渡。
        final ArgbEvaluator evaluator = new ArgbEvaluator();

        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                // 更新顏色
                int colorUpdate =
                        (Integer) evaluator.evaluate(
                                positionOffset,
                                colorList[position],
                                colorList[position == 2 ? position : position + 1]);
                mViewPager.setBackgroundColor(colorUpdate);
            }

            @Override
            public void onPageSelected(int position) {
                // 更新當前角標位置
                currentPage = position;
                updateIndicators(currentPage);

                switch (position) {
                    case 0:
                        mViewPager.setBackgroundColor(color1);
                        break;
                    case 1:
                        mViewPager.setBackgroundColor(color2);
                        break;
                    case 2:
                        mViewPager.setBackgroundColor(color3);
                        break;
                }

                btn_skip.setVisibility(position == 0 ? View.VISIBLE : View.GONE);
                btn_finish.setVisibility(position == 2 ? View.VISIBLE : View.GONE);
                mNextBtn.setVisibility(position == 2 ? View.GONE : View.VISIBLE);
            }

            @Override
            public void onPageScrollStateChanged(int i) {

            }
        });

    }

    /**
     * 通過切換兩個不同的drawable來更新指示器。
     */
    private void updateIndicators(int position) {
        for (int i = 0; i < indicators.length; i++) {
            indicators[i].setBackgroundResource(
                    i == position ? R.drawable.indicator_selected : R.drawable.indicator_unselected
            );
        }
    }


    private void initView() {
        mViewPager = (ViewPager) findViewById(R.id.container);
        btn_skip = (Button) findViewById(R.id.btn_skip);
        image_indicator_zero = (ImageView) findViewById(R.id.image_indicator_zero);
        image_indicator_one = (ImageView) findViewById(R.id.image_indicator_one);
        image_indicator_two = (ImageView) findViewById(R.id.image_indicator_two);
        btn_finish = (Button) findViewById(R.id.btn_finish);
        mNextBtn = (ImageButton) findViewById(R.id.btn_next);

        btn_skip.setOnClickListener(this);
        btn_finish.setOnClickListener(this);
        mNextBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_skip:
                gotoMain();
                break;
            case R.id.btn_finish:
                Utils.saveSharedSetting(PagerActivity.this, "isGuide", true);
                gotoMain();
                break;
            case R.id.btn_next:
                currentPage += 1;
                if (currentPage > 2) {
                    currentPage = 2;
                }
                mViewPager.setCurrentItem(currentPage, true);
                break;
            default:
                break;
        }
    }
}

註釋寫的很清楚,看程式碼完全OK的呢。

然後就是ViewPager的介面卡

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

import com.yunyang.yunyangblogdemo.fragment.GuideFragment;

/**
 * 作者    yunyang
 * 時間    2018/11/13 11:20
 * 檔案    YunyangBlogDemo
 * 描述   引導頁ViewPager的介面卡
 */
public class GuidePagerAdapter extends FragmentPagerAdapter {

    public GuidePagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        return GuideFragment.newInstance(position + 1);

    }

    @Override
    public int getCount() {
        return 3;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
            case 0:
                return "PAGE ONE";
            case 1:
                return "PAGE TWO";
            case 2:
                return "PAGE THREE";
        }
        return null;
    }

}

以及ViewPager中包含的Fragment檔案

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view
            
           

相關推薦

使用ViewPager+Fragment製作Material DesignMD風格引導

使用ViewPager+Fragment製作Material Design(MD)風格的炫酷引導頁 我記得之前寫過一篇關於ViewPager+Fragment製作引導頁的Blog。 使用ViewPager+Fragment製作一個簡單的引導頁,外加一個簡易的Indicator圓形

Android Material Design動畫篇

揭露動畫 效果: 簡介: 背景擴散從某一個點向四周展開或者從四周向某一點聚合起來,類似波紋的效果,可以給任意的View新增這種效果。 顯示或隱藏一組 UI 元素時,揭露動畫可為使用者提供視覺連續性; 使用: Android Sdk 中已經幫我們提供了一個工具

Android玩 --- Material Design1 --- Recycleview基本使用1

一不小心就寫了個很長的題目啊,估計大家也能猜到這樣做的意圖(intent!)是啥了,作為一個小白開發者,能做的就是不斷整理筆記,既方便了自己,也為更多小白指引道路,何樂而不為呢。我的標題分了三級,Android玩,表示這是Android的文章(廢話!),M

Android Material Design史上最全的材料設計控制元件大全

主要內容: 本文將要介紹Material design和Support library控制元件,主要包括TextInputLayout、SwitchCompat、SnackBar、FloatingActionButton、Shadows

ViewPager+ Fragment結合的setUserVisibleHint呼叫時機

    最近的專案使用到了ViewPager + Fragment的模式,要求在每次Fragment獲取顯示的時候來重新整理資料,該專案下ViewPager有5個子fragment,在onCreateView及fragment的setUserVisibleHint(bool is

第一行程式碼----Material Design1-3

今天看完了第一行程式碼的第十二章,順手寫篇部落格就當是複習總結吧,大家有什麼想法也可以提出來一起討論討論,能一起進步當然是最好的哈! 本章節共分為8個小節,個別小節又有不止一個知識點,所以總體來說這章的內容蠻多的呢,需要我們認真對待哦! 1.什麼是Materia

第一行程式碼----Material Design6-7

6.下拉重新整理 本節我們繼續在前面的基礎上進行改進,加入下拉重新整理功能,該功能的實現需要使用SwipeRefreshLayout,對誰使用呢?當然是我們的RecycleView控制元件啦! 修改activity_main.xml程式碼,在RecycleVie

安卓日記——玩轉Material DesignNavigationView篇

最近突然對Material Design感興趣,然後想看看怎麼玩。 首先要說的是NavigationView,就是我們經常要用到的側邊導航欄 在沒有NavigationView之前我們用的是普通的LinearLayout+ListView+頭部layout

Fragment全解析系列:正確的使用姿勢

Fragment是可以讓你的app縱享絲滑的設計,如果你的app想在現在基礎上效能大幅度提高,並且佔用記憶體降低,同樣的介面Activity佔用記憶體比Fragment要多,響應速度Fragment比Activty在中低端手機上快了很多,甚至能達到好幾倍!如果你的app當前或以後有移植平板等平臺時,

Fragment全解析系列:那些年踩過的坑

本篇主要介紹一些最常見的Fragment的坑以及官方Fragment庫的那些自身的BUG,並給出解決方案;這些BUG在你深度使用時會遇到,比如Fragment巢狀時或者單Activity+多Fragment架構時遇到的坑。 Fragment是可以讓你的app縱享絲滑的設計,如果你的app想在

遊戲製作之路26Camera攝像機的清除標誌Depth only

在前面學習了天空盒和純背景顏色的清除方法,這兩個方法都比較常用的,一般情況下使用這兩個選項,就基本滿足了。但是你或許有點好奇心,像一個小學生一樣,不斷地為什麼,比如為什麼太陽會發亮,為什麼月亮只有晚上才看到,為什麼老師要讓我背書等等問題,多問為什麼,的確是一個好學生的樣子。因而,繼續來追問下一個

遊戲製作之路25Camera攝像機的清除標誌Solid color

前面學習了清除標誌skybox的使用,接著下來,來學習一下Solid color的使用。當一個遊戲畫面沒有背景圖時,可以使用一個純顏色的背景來顯示。比如想開發一個演示動畫的時候,在我們上大學的時候,很多老師都想把課堂做得最好,所以常常使用電腦作為輔助手段。特別在上物理課時,很多實驗現象是需要動畫

遊戲製作之路24Camera攝像機的清除標誌Skybox

在前面學習了攝像機的屬性:Clear Flags,知道它有四個選項,但是什麼時候使用哪一個選項呢?這是一個必須學習會的知識點,否則你是做不出來遊戲的,就像數學裡充分必要條件一樣。由於攝像機的重要性,就因為遊戲顯示的一切都是從它顯示出來的。在這裡先來學習第一個選項:Skybox(天空盒)。 什麼是

Viewpager的使用簡單認識1

viewpager的是為了 實現左右滑動切換頁面的效果, 常用於與導航欄和 廣告欄 ViewPager+Fragment配合使用。 1.ViewPager類需要一個PagerAdapter介面卡類給它提供資料。 2.Viewpager 繼承自viewgroup是一個容器類。 1.簡

使用Python3將Markdown.md文字轉換成 html、pdf

一、Markdown中不同的文字內容會分成不同的文字塊,並通過markdown的語法控制進行文字的拼接,組成新的檔案。   二、利用Python3實現(.md)檔案轉換成(.html)檔案   在cmd命令列下進入(.py)檔案目錄下,使用命令進行執行   >python md2htm

使用Python3將Markdown.md文本轉換成 html、pdf

isp break 段落 close all ict ddr tran 有序 一、Markdown中不同的文本內容會分成不同的文本塊,並通過markdown的語法控制進行文本的拼接,組成新的文件。 二、利用Python3實現(.md)文件轉換成(.html)文件

P3650 [USACO1.3]滑雪課程設計Ski Course Design暴力

題目描述 農民約翰的農場裡有N座山峰(1<=N<=1000),每座山都有一個在0到100之間的整數的海拔高度。在冬天,因為山上有豐富的積雪,約翰經常開辦滑雪訓練營。 不幸的是,約翰剛剛得知稅法在滑雪訓練營方面有新變化,明年開始實施。在仔細閱讀法律後,他發現如果

Viewpager實現 輪播廣告欄BannerPager

實現這個功能的目前已經有很多種方式了,譬如說繼承ViewGroup仿ViewPager通過adapter迴圈add、dstory指定的item,使用fragment新增移除view的方式,設定viewpager的索引條目達到上限==。以上幾種方式屬於Banner的常用選擇,其中動效做的非

VS中的多執行緒/MT、多執行緒除錯/MTd、多執行緒DLL/MD、多執行緒除錯DLL/MDd的區別

一種語言的開發環境往往會附帶有語言庫,這些庫就是對作業系統的API的包裝,我們也稱這些語言庫為執行庫 對於MSVC的執行庫(CRT),按照靜態/動態連結,可以分為靜態版和動態版;按照除錯/釋出,可以分為除錯版本和釋出版本;按照單執行緒/多執行緒,可以分為單執行緒版本和多執行

[譯] MDC-101 Flutter:Material ComponentsMDC基礎Flutter

原文地址:MDC-101 Flutter: Material Components (MDC) Basics (Flutter) 原文作者:codelabs.developers.google.com 譯文出自:掘金翻譯計劃 本文永久連結:github.com/xitu/gol