1. 程式人生 > >Android使用ViewPager實現引導頁(帶小點提示)

Android使用ViewPager實現引導頁(帶小點提示)

介紹

       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() ..."造成程式結束。

提示我們要新增的View已經繫結一個父類,由於一個子view不能與兩個父類相關,所以必須得解綁。

因此必須在此之前新增判斷,如果已經綁定了一個父類,必須先解綁再新增到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



原始碼

http://download.csdn.net/detail/alfred_c/9106361