ViewPager 從入門到帶你擼個啓動頁之實戰啓動頁(三)

轉載請註明出處(萬分感謝!):
http://blog.csdn.net/javazejian/article/details/52144889

關聯文章:

ViewPager 從入門到帶你擼個啓動頁之ViewPager基礎入門(一)

ViewPager 從入門到帶你擼個啓動頁之Fragment+ViewPager(二)

ViewPager 從入門到帶你擼個啓動頁之實戰啓動頁(三)

ViewPager 從入門到帶你擼個啓動頁之實戰PageTransformer切換動畫特效(四)

一、啓動頁實現概述

  通過前兩篇的分享,我們已經基本掌握了ViewPager的基本使用,本篇咱們就來實現一個通用的啓動頁,先來看看啓動頁效果:

  看來效果還不錯,但實際上只用了ViewPager,並沒有用到Fragment,因爲移動就是3張圖片而已,所以PagerAdapter的實現類代碼也是相當簡單的。唯一比較棘手的是頁面移動過程中底部的3個小點也必須跟着移動,這點需要配合ViewPager的滑動監聽動態實時小圓點的移動位置。下面我們就來分析它的實現過程吧。

二、啓動頁實現過程

2.1 實現整體滑動效果

  首先我們先來實現整體的滑動效果,也就是添加3張圖片作爲ViewPager的滑動頁面,因此我們的activity_guide.xml如下:

<?xml version="1.0" encoding="utf-8"?>
<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="fill_parent"
        android:layout_height="fill_parent" >
    </android.support.v4.view.ViewPager>

</RelativeLayout>

接下來我們創建GuideActivity.java:

package com.zejian.commonstartpage;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ImageView;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by zejian
 * Time 16/8/7.
 * Description:
 */
public class GuideActivity extends Activity{
    // ViewPager的數據
    private List<ImageView> imageViewList;
    ViewPager mViewPager;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 去標題, 需要在setContentView方法之前調用
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_guide);
        initView();// 初始化控件
    }

    /**
     * 初始化控件
     */
    private void initView() {
        mViewPager = (ViewPager) findViewById(R.id.vp_guide);
        GuideAdapter adapter = new GuideAdapter();
        mViewPager.setAdapter(adapter);
}

    /**
     * TODO:初始化ViewPager數據 void
     */
    private void initData() {
        int[] imageResIDs = {R.drawable.guide_1, R.drawable.guide_2,
                R.drawable.guide_3};
        imageViewList = new ArrayList<>();

        ImageView iv;// 圖片

        for (int i = 0; i < imageResIDs.length; i++) {
            iv = new ImageView(this);
            iv.setBackgroundResource(imageResIDs[i]);
            imageViewList.add(iv);
        }
    }



    class GuideAdapter extends PagerAdapter {

        @Override
        public int getCount() {
            return imageViewList.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        /*
         * 刪除元素
         */
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            ImageView iv = imageViewList.get(position);
            container.addView(iv);// 1. 向ViewPager中添加一個view對象
            return iv; // 2. 返回當前添加的view對象
        }
    }
}

  我們簡單說一下代碼,首先我們通過initData方法去創建我們所需需要的界面,因爲我們的界面都是圖片,所以這裏我們直接new出3個ImageView控件,並設置圖片即可,最後我們把其添加到imageViewList數據集合中,到此數據初始化完成:

 /**
* 初始化ViewPager數據 
*/
private void initData() {
   int[] imageResIDs = {R.drawable.guide_1, R.drawable.guide_2,
           R.drawable.guide_3};
   imageViewList = new ArrayList<>();

   ImageView iv;// 圖片

   for (int i = 0; i < imageResIDs.length; i++) {
       iv = new ImageView(this);
       iv.setBackgroundResource(imageResIDs[i]);
       imageViewList.add(iv);
   }
}

  接着我們創建GuideAdapter數據適配器繼承自PagerAdapter,重寫其方法,返回我們所需要的界面,這個前兩篇已經說得很清楚了,這裏不過多分析了。最後我們把數據適配器GuideAdapter設置給ViewPager即可:

mViewPager = (ViewPager) findViewById(R.id.vp_guide);
GuideAdapter adapter = new GuideAdapter();
mViewPager.setAdapter(adapter);

到此啓動頁初步實現完成,我們運行一下,看看效果。

不錯!預期效果已經開始出現。接下來我們先把最後一頁的按鈕添加上。

2.2 添加按鈕

  需要添加按鈕的話我們就必須修改activity_guide.xml文件,添加一個按鈕如下:

<?xml version="1.0" encoding="utf-8"?>
<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="fill_parent"
        android:layout_height="fill_parent" >
    </android.support.v4.view.ViewPager>

    <Button
        android:id="@+id/btn_guide_start_experience"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="60dip"
        android:background="@drawable/button_bg"
        android:textColor="@drawable/button_textcolor"
        android:text="開始體驗"
        android:textSize="20sp" 
        android:paddingLeft="20dip"
        android:paddingRight="20dip"
        android:paddingTop="5dip"
        android:paddingBottom="5dip"
        android:visibility="gone"
        />
</RelativeLayout>

  顯然我們添加了一個Button,並將其設置在父佈局的底部而且水平居中,注意此時按鈕先設置爲gone,待需要顯示時再設置其可見。然後我們在Activity_Guide.java中添加如下代碼:

btnStartExperience = (Button) findViewById(R.id.btn_guide_start_experience)
//設置監聽器
btnStartExperience.setOnClickListener(this);

  設置完按鈕的點擊事件後,我們還需要解決一個問題,那就是當需要顯示Button時再顯示出來,很顯然,我們只需在第3頁時才需要顯示按鈕,這時我們就需要藉助ViewPager的滑動事件來處理了,因此我們實現ViewPager.OnPageChangeListener接口,並實現其方法如下:

    /**
     * 當頁面正在滾動時 position 當前選中的是哪個頁面 positionOffset 比例 positionOffsetPixels 偏移像素
     */
    @Override
    public void onPageScrolled(int position, float positionOffset,
                               int positionOffsetPixels) {
    }

    /**
     * 當頁面被選中
     */
    @Override
    public void onPageSelected(int position) {

    }

    /**
     * 當頁面滾動狀態改變
     */
    @Override
    public void onPageScrollStateChanged(int state) {

    }

簡單介紹一下三個方法:

  • onPageScrolled(int position, float positionOffset,
    int positionOffsetPixels)

    當頁面正在滾動時被回調。
    position 表示當前選中的是第幾個頁面;
    positionOffset 是當前頁面滑動比例,其值得範圍是[0,1),如果頁面向右翻動,這個值不斷變大,最後在趨近1的情況後突變爲0。如果頁面向左翻動,這個值不斷變小,最後變爲0。
    positionOffsetPixels 是當前頁面滑動像素的偏移距離

  • onPageScrollStateChanged(int state)
    當頁面滾動狀態改變時被回調。有三個值:0(END),1(PRESS) , 2(UP) 。
    當用手指滑動翻頁時,手指按下去的時候會觸發這個方法,state值爲1,手指擡起時,如果發生了滑動(即使很小),其值會變爲2,最後變爲0 。總共執行這個方法三次。噹噹前頁面翻頁時,會執行這個方法兩次,state值分別爲2 , 0 。

  • onPageSelected(int position)
    當頁面被選中時回調,position表示被選中的頁面,position下標從0開始計算。

  很顯然,我們應該利用onPageSelected(int position)決定實現我們的Button是否展示,當position爲最後一個頁面時展示,其他時候都隱藏即可。代碼如下:

 /**
 * 當頁面被選中
 */
@Override
public void onPageSelected(int position) {
    // 顯示體驗按鈕
    if (position == imageViewList.size() - 1) {
        // 顯示
        btnStartExperience.setVisibility(View.VISIBLE);
    } else {
        btnStartExperience.setVisibility(View.GONE);// 隱藏
    }
}

到此按鈕也集成完,我們看看整體GuideActivity代碼:


package com.zejian.commonstartpage;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by zejian
 * Time 16/8/7.
 * Description:
 */
public class GuideActivity extends Activity implements ViewPager.OnPageChangeListener, View.OnClickListener {
    // ViewPager的數據
    private List<ImageView> imageViewList;
    // 開始體驗按鈕
    private Button btnStartExperience;
    // ViewPager
    ViewPager mViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 去標題, 需要在setContentView方法之前調用
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_guide);
        initView();// 初始化控件
    }

    /**
     * 初始化控件
     */
    private void initView() {
        mViewPager = (ViewPager) findViewById(R.id.vp_guide);
        btnStartExperience = (Button) findViewById(R.id.btn_guide_start_experience);
        initData();// 初始化ViewPager數據
        GuideAdapter adapter = new GuideAdapter();
        mViewPager.setAdapter(adapter);
        mViewPager.setOnPageChangeListener(this);// 設置監聽器
        btnStartExperience.setOnClickListener(this);// 按鈕添加監聽
    }

    /**
     * TODO:初始化ViewPager數據 void
     */
    private void initData() {
        int[] imageResIDs = {R.drawable.guide_1, R.drawable.guide_2,
                R.drawable.guide_3};
        imageViewList = new ArrayList<>();

        ImageView iv;// 圖片

        for (int i = 0; i < imageResIDs.length; i++) {
            iv = new ImageView(this);
            iv.setBackgroundResource(imageResIDs[i]);
            imageViewList.add(iv);
        }
    }


    /**
     * 當頁面正在滾動時 position 當前選中的是哪個頁面 positionOffset 比例 positionOffsetPixels 偏移像素
     */
    @Override
    public void onPageScrolled(int position, float positionOffset,
                               int positionOffsetPixels) {
    }

    /**
     * 當頁面被選中
     */
    @Override
    public void onPageSelected(int position) {
        // 顯示體驗按鈕
        if (position == imageViewList.size() - 1) {
            btnStartExperience.setVisibility(View.VISIBLE);// 顯示
        } else {
            btnStartExperience.setVisibility(View.GONE);// 隱藏
        }
    }

    /**
     * 當頁面滾動狀態改變
     */
    @Override
    public void onPageScrollStateChanged(int state) {

    }

    /**
     * 打開新的界面
     */
    @Override
    public void onClick(View v) {
        Toast.makeText(getApplicationContext(), "跳轉新界面", Toast.LENGTH_SHORT).show();
    }


    class GuideAdapter extends PagerAdapter {

        @Override
        public int getCount() {
            return imageViewList.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        /*
         * 刪除元素
         */
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            ImageView iv = imageViewList.get(position);
            container.addView(iv);// 1. 向ViewPager中添加一個view對象
            return iv; // 2. 返回當前添加的view對象
        }
    }
}

我們運行看看其效果:

2.3 添加指示器

  終於到最後一步了,也是比較麻煩的一步,爲每一個頁面添加指示器,而且指示器必須跟隨頁面的移動而移動。那就先從佈局開始吧,我們在activity_guide.xml文件最下方添加如下代碼:

<RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="30dip">

        <LinearLayout
            android:id="@+id/ll_guide_point_group"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"></LinearLayout>

        <View
            android:id="@+id/select_point"
            android:layout_width="10px"
            android:layout_height="10px"
            android:background="@drawable/point_select" />
</RelativeLayout>

  我們在佈局中添加了一個相對佈局,其中包含了一個id爲ll_guide_point_group的LinearLayout,這個線性佈局主要用於存放指示器列表也就是3個灰色圓點,而另外一個id爲select_point的View則是表示一個被選中的紅色圓點。接下來我們就先來初始化這些點列表指示器的數據,因爲灰色圓點的數量跟啓動頁面的數量是一致的,所以有多少個頁面就有多少個灰色圓點,因此我們只需在生成圖片時同時生成灰色圓點即可,每個點的寬高都爲10,相隔距離也爲10,代碼如下:

private void initData() {
        int[] imageResIDs = { R.drawable.guide_1, R.drawable.guide_2,
                R.drawable.guide_3 };
        imageViewList = new ArrayList<ImageView>();

        ImageView iv;// 圖片
        View view;// 點
        LayoutParams params; // 參數類

        for (int i = 0; i < imageResIDs.length; i++) {
            iv = new ImageView(this);
            iv.setBackgroundResource(imageResIDs[i]);
            imageViewList.add(iv);
            // 根據圖片的個數, 每循環一次向LinearLayout中添加一個點
            view = new View(this);
            view.setBackgroundResource(R.drawable.point_normal);
            // 設置參數
            params = new LayoutParams(10, 10);
            if (i != 0) {
                params.leftMargin = 10;
            }
            view.setLayoutParams(params);// 添加參數
            llPointGroup.addView(view);
        }
    }

  從代碼我們可以看出,根據圖片的個數, 每循環一次向LinearLayout(llPointGroup)中添加一個點,最後便可以生成與圖片數量相同的灰色圓點。現在我們來運行一下,看看點的效果:

  嗯,小圓點已經出現,接下來就是如何移動的問題了。現在我們需要實現的效果是這樣的,當我們滑動頁面時,紅色小圓點也跟着移動,例如當頁面滑動到屏幕的一半時,紅色小圓點也應處於灰色圓點的中間位置。如下圖:

  因此,我們去動態計算頁面滑動的比例,然後按相同比例去計算紅色小圓點需要滑動的距離。比如當第1頁往第0頁滑動到中間時,此時小紅點的滑動距離應該如下計算:

  我們假設屏幕寬度爲320px,那麼當第1頁滑動到屏幕中間時,其滑動距離就是160,此時滑動比較就是160/320=0.5,也就是說紅色小圓點的滑動比例也是0.5,通過這個滑動比例我們就可以計算出兩個點間的滑動距離,我們可以通過以下方式計算出小紅點要滑動的距離:
pWidth=llPointGroup.getChildAt(1).getLeft()-llPointGroup.getChildAt(0).getLeft()
  最後乘以滑動比例就是小紅點的滑動距離了。當然這只是其中一次滑動的完整計算過程,頁面滑動過程中的小紅點變化的計算方式也是相同(因爲滑動過程中會多次調用onPageScrolled方法後面會說明),現在剩下的問題是我們如何知道頁面滑動過程呢?還記得前面我們ViewPager設置的OnPageChangeListener監聽器吧?其中有個回調方法onPageScrolled(int position, float positionOffset, int positionOffsetPixels)的參數positionOffset不就是頁面的滑動比例嗎?確實如此,因此我們可以利用這個滑動比例來動態計算小紅點的滑動距離,這樣也就可以達到頁面滑動的過程中小紅點也跟隨移動的效果。下面我們給出實現代碼:

/**
* 當頁面正在滾動時 position 當前選中的是哪個頁面 positionOffset 比例 positionOffsetPixels 偏移像素
*/
@Override
public void onPageScrolled(int position, float positionOffset,
                          int positionOffsetPixels) {
   //獲取兩個點間的距離,獲取一次即可
   if(pWidth==0) {
       pWidth = llPointGroup.getChildAt(1).getLeft()
               - llPointGroup.getChildAt(0).getLeft();
   }

   // 獲取點要移動的距離
   int leftMargin = (int) (pWidth * (position + positionOffset));
   // 給紅點設置參數
   RelativeLayout.LayoutParams params = (android.widget.RelativeLayout.LayoutParams) mSelectPointView
           .getLayoutParams();
   params.leftMargin = leftMargin;
   mSelectPointView.setLayoutParams(params);
}

這裏我們再來簡單分析一下計算移動距離的代碼:

// 獲取點要移動的距離
int leftMargin = (int) (pWidth * (position + positionOffset));

  由於position表示當前頁面的下標,取值範圍在[0,2],而positionOffset則表示當前界面的滑動比例,取值範圍在[0,1),當頁面向右滑動,positionOffset值不斷變大,最後在趨近1的情況後突變爲0。如果頁面向左滑動,這個值不斷變小,最後變爲0,當positionOffset突變爲0時則說明頁面已處於展示位置。因此當我們把當前頁面往左滑動時,當前position=0,而positionOffset則在不斷的增大,我們過Log來觀察一下

當第0頁滑動到左側,而第1頁正好在中間展示時,position=1,而positionOffset=0;

  因此我們可以通過positionOffset的值來計算小紅點的滑動距離,噹噹前頁面往左滑動時,positionOffset不斷增大,此時由於position=0;所以pWidth * (position + positionOffset)也在不斷增大,計算出小紅點的移動距離leftMargin後,我們只需動態設置其params.leftMargin參數即可,這也就達到了小紅點跟隨移動的目的(onPageScrolled函數在移動中多次被觸發),最終position=1,positionOffset=0,小紅點也剛好落在了第2個灰色小圓點上。往後第3個點原理也是一樣的,向右移動也依次類推即可。。
最後我們給出GuideActivity的代碼:

package com.zejian.commonstartpage;


import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.RelativeLayout;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by zejian
 * Time 16/8/7.
 * Description:
 */
public class GuideActivity extends Activity implements ViewPager.OnPageChangeListener, View.OnClickListener {
    // ViewPager的數據
    private List<ImageView> imageViewList;
    // 點的組
    private LinearLayout llPointGroup;
    // 選中的點view對象
    private View mSelectPointView;
    // 開始體驗按鈕
    private Button btnStartExperience;
    // ViewPager
    ViewPager mViewPager;
    // 點之間的寬度
    private int pWidth;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 去標題, 需要在setContentView方法之前調用
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_guide);
        initView();// 初始化控件
    }

    /**
     * 初始化控件
     */
    private void initView() {
        mViewPager = (ViewPager) findViewById(R.id.vp_guide);
        btnStartExperience = (Button) findViewById(R.id.btn_guide_start_experience);
        llPointGroup = (LinearLayout) findViewById(R.id.ll_guide_point_group);
        mSelectPointView = findViewById(R.id.select_point);
        initData();// 初始化ViewPager數據
        GuideAdapter adapter = new GuideAdapter();
        mViewPager.setAdapter(adapter);
        mViewPager.setOnPageChangeListener(this);// 設置監聽器
        btnStartExperience.setOnClickListener(this);// 按鈕添加監聽
    }

    /**
     * TODO:初始化ViewPager數據 void
     */
    private void initData() {
        int[] imageResIDs = {R.drawable.guide_1, R.drawable.guide_2,
                R.drawable.guide_3};
        imageViewList = new ArrayList<>();

        ImageView iv;// 圖片
        View view;// 點
        LayoutParams params; // 參數類

        for (int i = 0; i < imageResIDs.length; i++) {
            iv = new ImageView(this);
            iv.setBackgroundResource(imageResIDs[i]);
            imageViewList.add(iv);
            // 根據圖片的個數, 每循環一次向LinearLayout中添加一個點
            view = new View(this);
            view.setBackgroundResource(R.drawable.point_normal);
            // 設置參數
            params = new LayoutParams(10, 10);
            if (i != 0) {
                params.leftMargin = 10;
            }
            view.setLayoutParams(params);// 添加參數
            llPointGroup.addView(view);
        }
    }


    /**
     * 當頁面正在滾動時 position 當前選中的是哪個頁面 positionOffset 比例 positionOffsetPixels 偏移像素
     */
    @Override
    public void onPageScrolled(int position, float positionOffset,
                               int positionOffsetPixels) {

        Log.e("zejian","positionOffset:-->"+positionOffset);
        Log.e("zejian","position:-->"+position);
        //獲取兩個點間的距離,獲取一次即可
        if(pWidth==0) {
            pWidth = llPointGroup.getChildAt(1).getLeft()
                    - llPointGroup.getChildAt(0).getLeft();
        }

        // 獲取點要移動的距離
        int leftMargin = (int) (pWidth * (position + positionOffset));
        // 給紅點設置參數
        RelativeLayout.LayoutParams params = (android.widget.RelativeLayout.LayoutParams) mSelectPointView
                .getLayoutParams();
        params.leftMargin = leftMargin;
        mSelectPointView.setLayoutParams(params);
    }

    /**
     * 當頁面被選中
     */
    @Override
    public void onPageSelected(int position) {
        // 顯示體驗按鈕
        if (position == imageViewList.size() - 1) {
            btnStartExperience.setVisibility(View.VISIBLE);// 顯示
        } else {
            btnStartExperience.setVisibility(View.GONE);// 隱藏
        }
    }

    /**
     * 當頁面滾動狀態改變
     */
    @Override
    public void onPageScrollStateChanged(int state) {

    }

    /**
     * 打開新的界面
     */
    @Override
    public void onClick(View v) {
        Toast.makeText(getApplicationContext(), "跳轉新界面", Toast.LENGTH_SHORT).show();
    }


    class GuideAdapter extends PagerAdapter {

        @Override
        public int getCount() {
            return imageViewList.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        /*
         * 刪除元素
         */
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            ImageView iv = imageViewList.get(position);
            container.addView(iv);// 1. 向ViewPager中添加一個view對象
            return iv; // 2. 返回當前添加的view對象
        }
    }
}

最近效果:

到此,啓動頁已全部完成,告本篇一段落。源碼下載:
啓動頁(commonstartpage項目)源碼GitHub下載地址

ViewPager 從入門到帶你擼個啓動頁之ViewPager基礎入門(一)

ViewPager 從入門到帶你擼個啓動頁之Fragment+ViewPager(二)

ViewPager 從入門到帶你擼個啓動頁之實戰啓動頁(三)

ViewPager 從入門到帶你擼個啓動頁之實戰PageTransformer切換動畫特效(四)

發佈了65 篇原創文章 · 獲贊 3504 · 訪問量 230萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章