ViewPager的運用

ViewPager

一般來說在Android開發中ViewPager的運用還算比較常見,比如說Android手機微信的界面之前的左右滑動的功能,還有比如說淘寶上廣告圖片的輪播效果。都是可以用ViewPager來實現和完成。
ViewPager繼承自ViewGroup,也就是ViewPager是一個容器類,可以包含其他的View類。?是一個允許使用者左右滑動數據頁面的布局管理器。你可以通過一個適配器(PagerAdapter)來管理要顯示的頁面。
PagerAdapter是用于“將多個頁面填充到ViewPager”的適配器的一個基類,大多數情況下,你們可能更傾向于使用一個實現了PagerAdapter并且更加具體的適配器

要通過自己寫的一個適配器來繼承PagerAdapter的,其中有四個方法是必須重寫的。

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return list.size();
    }

    @Override
    public boolean isViewFromObject(View arg0, Object arg1) {
        // TODO Auto-generated method stub
        return arg0 == arg1;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        // TODO Auto-generated method stub
        container.addView(list.get(position));
        return list.get(position);
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        // TODO Auto-generated method stub
        container.removeView(list.get(position));
    }

1,getCount() // 獲取要滑動的控件的數量。?
2,isViewFromObject(View, Object) // 來判斷顯示的是否是同一張圖片,這里我們將兩個參數相比較返回即可

接下來的兩個方法是需要手動來添加到適配器中的。

3,instantiateItem(ViewGroup, int) // 當要顯示的圖片可以進行緩存的時候,會調用這個方法進行顯示圖片的初始化,我們將要顯示的ImageView加入到ViewGroup中,然后作為返回值返回即可
4,destroyItem(ViewGroup, int, Object) // PagerAdapter只緩存三張要顯示的圖片,如果滑動的圖片超出了緩存的范圍,就會調用這個方法,將圖片銷毀

在創建適配器的同時也要在適配器創建一個構造方法(構造方法的參數是根據要傳的數據內容來給定的)
然后在你的Activity中調用適配器就OK了。


viewpager不直接處理每一個視圖而是將各個視圖與一個鍵聯系起來。這個鍵用來跟蹤且唯一代表一個頁面,不僅如此,該鍵還獨立于這個頁面所在adapter的位置。當pageradapter將要改變的時候他會調用startUpdate函數,接下來會調用一次或多次的instantiateItem或者destroyItem。最后在更新的后期會調用finishUpdate。當finishUpdate返回時 instantiateItem返回的對象應該添加到父ViewGroup destroyItem返回的對象應該被ViewGroup刪除。
isViewFromObject(View, Object)代表了當前的頁面是否與給定的鍵相關聯。
isViewFromObject
功能:該函數用來判斷instantiateItem(ViewGroup, int)函數所返回來的Key與一個頁面視圖是否是代表的同一個視圖(即它倆是否是對應的,對應的表示同一個View)
返回值:如果對應的是同一個View,返回True,否則返回False。


還有沒有結束,這才剛剛開始,接下來處理ViewPager滑動的事件;
給ViewPager設置監聽的接口是OnPageChangeListener。當去實現這個接口的時候回重寫其中的一下方法:

public void onPageScrollStateChanged(int arg0) {

    // TODO Auto-generated method stub

}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
    // TODO Auto-generated method stub

}

@Override
public void onPageSelected(int arg0) {
    // TODO Auto-generated method stub
    
}

現在我們是做簡單的微信滑動的功能的話,只需要在onPageSelected()中添加滑動事件就可以。


簡單說一下上述三種方法的作用
onPageScrollStateChanged(int arg0) ,此方法是在狀態改變的時候調用,其中arg0這個參數
有三種狀態(0,1,2)。arg0 ==1的正在滑動,arg0==2的滑動完畢了,arg0==0的什么都沒做。
當頁面開始滑動的時候,三種狀態的變化順序為(1,2,0)

onPageScrolled(int arg0,float arg1,int arg2) ,當頁面在滑動的時候會調用此方法,在滑動被停止之前,此方法回一直得到
調用。其中三個參數的含義分別為:
arg0 :當前頁面,及你點擊滑動的頁面
arg1:當前頁面偏移的百分比
arg2:當前頁面偏移的像素位置

onPageSelected(int arg0) : 此方法是頁面跳轉完后得到調用,arg0是你當前選中的頁面的Position(位置編號)。


ViewPager更多的時候會與Fragment一起使用。Android提供了一些專門的適配器來讓ViewPager與Fragment一起工作,也就是FragmentPagerAdapter與FragmentStatePagerAdapter。他們基本上可以滿足大部分常見的需求?
在大部分時候,項目中的ViewPager會和Fragment同時出現,每一個ViewPager的頁面就是一個Fragment(微信主頁)?Android提供了一些專門的適配器來讓ViewPager與Fragment一起工作,也就是FragmentPagerAdapter與FragmentStatePagerAdapter。

FragmentPagerAdapter繼承自PagerAdapter ,主要用來展示多個Fragment頁面,并且每一個Fragment都會被保存在fragment manager中。
FragmentPagerAdapter最適用于那種少量且相對靜態的頁面,例如幾個tab頁。每一個用戶訪問過的fragment都會被保存在內存中對于較多的頁面集合,更推薦使用FragmentStatePagerAdapter。

FragmentStatePagerAdapter繼承自PagerAdapter,主要使用Fragment來管理每個頁面。這個類同樣用來保存和恢復fragment頁面的狀態。
FragmentStatePagerAdapter更多用于大量頁面,例如視圖列表。當某個頁面對用戶不再可見時,他們的整個fragment就會被銷毀,僅保留fragment狀態。相比于FragmentPagerAdapter,這樣做的好處是在訪問各個頁面時能節約大量的內存開銷,但代價是在頁面切換時會增加非常多的開銷。
FragmentPagerAdapter與FragmentStatePagerAdapter存在著大量相似之處,用法也差不多,他們之間最大的不同在于:用戶訪問過的頁面不可見之后是否會保留在內存中,而這個區別也構成了他們使用場景的不同。


import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

public class SplashActivity extends Activity {
boolean isFirstIn = false;

private static final int GO_HOME = 1000;  
private static final int GO_GUIDE = 1001;  
// 延遲3秒  
private static final long SPLASH_DELAY_MILLIS = 3000;  

private static final String SHAREDPREFERENCES_NAME = "first_pref";  

/** 
 * Handler:跳轉到不同界面 
 */  
private Handler mHandler = new Handler() {  

    @Override  
    public void handleMessage(Message msg) {  
        switch (msg.what) {  
        case GO_HOME:  
            goHome();  
            break;  
        case GO_GUIDE:  
            goGuide();  
            break;  
        }  
        super.handleMessage(msg);  
    }  
};  

@Override  
protected void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
    setContentView(R.layout.splash);  

    init();  
}  

private void init() {  
    // 讀取SharedPreferences中需要的數據  
    // 使用SharedPreferences來記錄程序的使用次數  
    SharedPreferences preferences = getSharedPreferences(  
            SHAREDPREFERENCES_NAME, MODE_PRIVATE);  

    // 取得相應的值,如果沒有該值,說明還未寫入,用true作為默認值  
    isFirstIn = preferences.getBoolean("isFirstIn", true);  

    // 判斷程序與第幾次運行,如果是第一次運行則跳轉到引導界面,否則跳轉到主界面  
    if (!isFirstIn) {  
        // 使用Handler的postDelayed方法,3秒后執行跳轉到MainActivity  
        mHandler.sendEmptyMessageDelayed(GO_HOME, SPLASH_DELAY_MILLIS);  
    } else {  
        mHandler.sendEmptyMessageDelayed(GO_GUIDE, SPLASH_DELAY_MILLIS);  
    }  

}  

private void goHome() {  
    Intent intent = new Intent(SplashActivity.this, MainActivity.class);  
    SplashActivity.this.startActivity(intent);  
    SplashActivity.this.finish();  
}  

private void goGuide() {  
    Intent intent = new Intent(SplashActivity.this, GuideActivity.class);  
    SplashActivity.this.startActivity(intent);  
    SplashActivity.this.finish();  
}  

}
GuideActivity.java引導界面


import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import cn.eoe.leigo.splash.adapter.ViewPagerAdapter;

public class GuideActivity extends Activity implements OnPageChangeListener {

private ViewPager vp;  
private ViewPagerAdapter vpAdapter;  
private List<View> views;  

// 底部小點圖片  
private ImageView[] dots;  

// 記錄當前選中位置  
private int currentIndex;  

@Override  
protected void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
    setContentView(R.layout.guide);  

    // 初始化頁面  
    initViews();  

    // 初始化底部小點  
    initDots();  
}  

private void initViews() {  
    LayoutInflater inflater = LayoutInflater.from(this);  

    views = new ArrayList<View>();  
    // 初始化引導圖片列表  
    views.add(inflater.inflate(R.layout.what_new_one, null));  
    views.add(inflater.inflate(R.layout.what_new_two, null));  
    views.add(inflater.inflate(R.layout.what_new_three, null));  
    views.add(inflater.inflate(R.layout.what_new_four, null));  

    // 初始化Adapter  
    vpAdapter = new ViewPagerAdapter(views, this);  
      
    vp = (ViewPager) findViewById(R.id.viewpager);  
    vp.setAdapter(vpAdapter);  
    // 綁定回調  
    vp.setOnPageChangeListener(this);  
}  

private void initDots() {  
    LinearLayout ll = (LinearLayout) findViewById(R.id.ll);  

    dots = new ImageView[views.size()];  

    // 循環取得小點圖片  
    for (int i = 0; i < views.size(); i++) {  
        dots[i] = (ImageView) ll.getChildAt(i);  
        dots[i].setEnabled(true);// 都設為灰色  
    }  

    currentIndex = 0;  
    dots[currentIndex].setEnabled(false);// 設置為白色,即選中狀態  
}  

private void setCurrentDot(int position) {  
    if (position < 0 || position > views.size() - 1  
            || currentIndex == position) {  
        return;  
    }  

    dots[position].setEnabled(false);  
    dots[currentIndex].setEnabled(true);  

    currentIndex = position;  
}  

// 當滑動狀態改變時調用  
@Override  
public void onPageScrollStateChanged(int arg0) {  
}  

// 當當前頁面被滑動時調用  
@Override  
public void onPageScrolled(int arg0, float arg1, int arg2) {  
}  

// 當新的頁面被選中時調用  
@Override  
public void onPageSelected(int arg0) {  
    // 設置底部小點選中狀態  
    setCurrentDot(arg0);  
}  

}
ViewPagerAdapter.java。ViewPager的適配器


import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import cn.eoe.leigo.splash.MainActivity;
import cn.eoe.leigo.splash.R;

/**
*/
public class ViewPagerAdapter extends PagerAdapter {

// 界面列表  
private List<View> views;  
private Activity activity;  
private static final String SHAREDPREFERENCES_NAME = "first_pref";  
public ViewPagerAdapter(List<View> views, Activity activity) {  
    this.views = views;  
    this.activity = activity;  
}  

// 銷毀arg1位置的界面  
@Override  
public void destroyItem(View arg0, int arg1, Object arg2) {  
    ((ViewPager) arg0).removeView(views.get(arg1));  
}  

@Override  
public void finishUpdate(View arg0) {  
}  

// 獲得當前界面數  
@Override  
public int getCount() {  
    if (views != null) {  
        return views.size();  
    }  
    return 0;  
}  

// 初始化arg1位置的界面  
@Override  
public Object instantiateItem(View arg0, int arg1) {  
    ((ViewPager) arg0).addView(views.get(arg1), 0);  
    if (arg1 == views.size() - 1) {  
        ImageView mStartWeiboImageButton = (ImageView) arg0  
                .findViewById(R.id.iv_start_weibo);  
        mStartWeiboImageButton.setOnClickListener(new OnClickListener() {  

            @Override  
            public void onClick(View v) {  
                // 設置已經引導  
                setGuided();  
                goHome();  

            }  

        });  
    }  
    return views.get(arg1);  
}  

private void goHome() {  
    // 跳轉  
    Intent intent = new Intent(activity, MainActivity.class);  
    activity.startActivity(intent);  
    activity.finish();  
}  
/** 
 *  
 * method desc:設置已經引導過了,下次啟動不用再次引導 
 */  
private void setGuided() {  
    SharedPreferences preferences = activity.getSharedPreferences(  
            SHAREDPREFERENCES_NAME, Context.MODE_PRIVATE);  
    Editor editor = preferences.edit();  
    // 存入數據  
    editor.putBoolean("isFirstIn", false);  
    // 提交修改  
    editor.commit();  
}  

// 判斷是否由對象生成界面  
@Override  
public boolean isViewFromObject(View arg0, Object arg1) {  
    return (arg0 == arg1);  
}  

@Override  
public void restoreState(Parcelable arg0, ClassLoader arg1) {  
}  

@Override  
public Parcelable saveState() {  
    return null;  
}  

@Override  
public void startUpdate(View arg0) {  
}  

}
至于MainActivity隨便了。
效果就是如下圖片

Paste_Image.png

Paste_Image.png

Paste_Image.png

Paste_Image.png

所以總結一下,我們可以使用ViewPager做什么:
1.程序使用導航,外加底部圓點的效果,這個在微信示例里介紹了
2.頁卡滑動,加上菜單的效果,不管是之前的支持手勢也支持底部圖標點擊的微信,還是今天的微博。


相互學習,共同努力!
微信號:romance-l

博客地址:http://my.csdn.net/?ref=toolbar

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容