Android使用ViewPager實現引導頁(帶小點提示)
阿新 • • 發佈:2019-02-04
介紹
ViewPager是一種允許使用者左右滑動頁面的佈局管理器,你需要寫一個類繼承PageAdapter來生成要展示的介面。
實現
一、 在佈局檔案中新增控制元件
<android.support.v4.view.ViewPager
android:id="@+id/vp_guide"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
二、寫一個類繼承PageAdapter
public class GuidePagerAdapter extends PagerAdapter { private List<View> views; public GuidePagerAdapter(List<View> views) { // TODO 自動生成的建構函式存根 this.views = views; } @Override public int getCount() { // TODO 自動生成的方法存根 return views.size(); } @Override public boolean isViewFromObject(View view, Object object) { // TODO 自動生成的方法存根 return view == object; } @Override public Object instantiateItem(ViewGroup container, int position) { // TODO 自動生成的方法存根 ViewGroup parent = (ViewGroup) views.get(position).getParent(); if (parent != null) parent.removeAllViews(); container.addView(views.get(position)); return views.get(position); } @Override public void destroyItem(ViewGroup container, int position, Object object) { // TODO 自動生成的方法存根 container.removeView(views.get(position)); } }
其中,getCount和isViewFromObject是必須覆寫的方法。isViewFromObject是用來判斷pager的一個view是否和instantiateItem方法返回的object有關聯,因為instantiateItem方法返回值不一定是view,可以是任意物件。
而當我們覆寫instantiateItem方法時,如果直接寫container.addView(views.get(position))的話會報
java.lang.IllegalStateException:
The specified child already has a parent. You must call removeView() ..."造成程式結束。
因此必須在此之前新增判斷,如果已經綁定了一個父類,必須先解綁再新增到ViewGroup裡:
ViewGroup parent = (ViewGroup) views.get(position).getParent();
if (parent != null)
parent.removeAllViews();
getCount和destroyItem方法就不贅餘了。三、呼叫setAdapter方法設定其為介面卡,傳入一個View的集合即可。
vpGuide = (ViewPager) findViewById(R.id.vp_guide);
vpGuide.setAdapter(new GuidePagerAdapter(getAllGuidePages()));
private List<View> getAllGuidePages() {
// TODO 自動生成的方法存根
List<View> views = new ArrayList<View>();
for(int i=0; i<4; i++){
views.add(getGuidePage(i));
}
return views;
}
private View getGuidePage(int i) {
// TODO 自動生成的方法存根
View v = View.inflate(this, R.layout.include_guide_page, null);
ImageView ivGuidePage = (ImageView) v.findViewById(R.id.iv_guide_page);
switch(i){
case 0:
ivGuidePage.setImageResource(R.drawable.page_guide_01);
break;
case 1:
ivGuidePage.setImageResource(R.drawable.page_guide_02);
break;
case 2:
ivGuidePage.setImageResource(R.drawable.page_guide_03);
break;
case 3:
ivGuidePage.setImageResource(R.drawable.page_guide_04);
break;
}
return ivGuidePage;
}
include_guide_page佈局檔案內容:<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="@+id/iv_guide_page"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter" />
</LinearLayout>
四:小點提示
佈局檔案如下,即一個線性佈局下包含四個ImageView,可以根據引導頁頁數自行增減。當前頁面的小點為淺藍色,其餘則為深藍色:
<LinearLayout
android:id="@+id/llt_page_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:layout_gravity="center_horizontal"
android:orientation="horizontal"
android:visibility="visible" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="5dp"
android:src="@drawable/page_indicator_bg" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="5dp"
android:src="@drawable/page_indicator_bg" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="5dp"
android:src="@drawable/page_indicator_bg" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="5dp"
android:src="@drawable/page_indicator_bg" />
</LinearLayout>
預設設定第一個小點為活躍狀態:
lltPageIndicator = (LinearLayout) findViewById(R.id.llt_page_indicator);
lltPageIndicator.getChildAt(0).setEnabled(false);
ViewPager控制元件呼叫setOnPageChangeListener方法判斷當前所在頁面。首先清除所有小點的活躍狀態,然後設定當前頁面對應的小點為活躍狀態,當滑至最後一頁時顯示進入應用的按鈕。
vpGuide.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int arg0) {
// TODO 自動生成的方法存根
clearIndicatorFocusedState();
lltPageIndicator.getChildAt(arg0).setEnabled(false);
if(arg0==3)
btnEntry.setVisibility(View.VISIBLE);
else
btnEntry.setVisibility(View.INVISIBLE);
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO 自動生成的方法存根
}
@Override
public void onPageScrollStateChanged(int arg0) {
// TODO 自動生成的方法存根
}
});
private void clearIndicatorFocusedState() {
// TODO 自動生成的方法存根
int childCount = lltPageIndicator.getChildCount();
for(int i=0; i<childCount; i++){
lltPageIndicator.getChildAt(i).setEnabled(true);
}
}
效果
參考
http://segmentfault.com/q/1010000000484617
http://www.th7.cn/Program/Android/201403/183702.shtml
原始碼