ViewPager的運(yùn)用

ViewPager

一般來說在Android開發(fā)中ViewPager的運(yùn)用還算比較常見澈吨,比如說Android手機(jī)微信的界面之前的左右滑動(dòng)的功能穷娱,還有比如說淘寶上廣告圖片的輪播效果恬涧。都是可以用ViewPager來實(shí)現(xiàn)和完成云芦。
ViewPager繼承自ViewGroup虚汛,也就是ViewPager是一個(gè)容器類拟赊,可以包含其他的View類。?是一個(gè)允許使用者左右滑動(dòng)數(shù)據(jù)頁面的布局管理器草慧。你可以通過一個(gè)適配器(PagerAdapter)來管理要顯示的頁面桶蛔。
PagerAdapter是用于“將多個(gè)頁面填充到ViewPager”的適配器的一個(gè)基類,大多數(shù)情況下漫谷,你們可能更傾向于使用一個(gè)實(shí)現(xiàn)了PagerAdapter并且更加具體的適配器

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

    @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() // 獲取要滑動(dòng)的控件的數(shù)量碟婆。?
2电抚,isViewFromObject(View, Object) // 來判斷顯示的是否是同一張圖片,這里我們將兩個(gè)參數(shù)相比較返回即可

接下來的兩個(gè)方法是需要手動(dòng)來添加到適配器中的竖共。

3蝙叛,instantiateItem(ViewGroup, int) // 當(dāng)要顯示的圖片可以進(jìn)行緩存的時(shí)候,會(huì)調(diào)用這個(gè)方法進(jìn)行顯示圖片的初始化公给,我們將要顯示的ImageView加入到ViewGroup中借帘,然后作為返回值返回即可
4,destroyItem(ViewGroup, int, Object) // PagerAdapter只緩存三張要顯示的圖片淌铐,如果滑動(dòng)的圖片超出了緩存的范圍肺然,就會(huì)調(diào)用這個(gè)方法,將圖片銷毀

在創(chuàng)建適配器的同時(shí)也要在適配器創(chuàng)建一個(gè)構(gòu)造方法(構(gòu)造方法的參數(shù)是根據(jù)要傳的數(shù)據(jù)內(nèi)容來給定的)
然后在你的Activity中調(diào)用適配器就OK了腿准。


viewpager不直接處理每一個(gè)視圖而是將各個(gè)視圖與一個(gè)鍵聯(lián)系起來际起。這個(gè)鍵用來跟蹤且唯一代表一個(gè)頁面,不僅如此吐葱,該鍵還獨(dú)立于這個(gè)頁面所在adapter的位置街望。當(dāng)pageradapter將要改變的時(shí)候他會(huì)調(diào)用startUpdate函數(shù),接下來會(huì)調(diào)用一次或多次的instantiateItem或者destroyItem唇撬。最后在更新的后期會(huì)調(diào)用finishUpdate。當(dāng)finishUpdate返回時(shí) instantiateItem返回的對象應(yīng)該添加到父ViewGroup destroyItem返回的對象應(yīng)該被ViewGroup刪除展融。
isViewFromObject(View, Object)代表了當(dāng)前的頁面是否與給定的鍵相關(guān)聯(lián)窖认。
isViewFromObject
功能:該函數(shù)用來判斷instantiateItem(ViewGroup, int)函數(shù)所返回來的Key與一個(gè)頁面視圖是否是代表的同一個(gè)視圖(即它倆是否是對應(yīng)的,對應(yīng)的表示同一個(gè)View)
返回值:如果對應(yīng)的是同一個(gè)View告希,返回True扑浸,否則返回False。


還有沒有結(jié)束燕偶,這才剛剛開始喝噪,接下來處理ViewPager滑動(dòng)的事件;
給ViewPager設(shè)置監(jiān)聽的接口是OnPageChangeListener指么。當(dāng)去實(shí)現(xiàn)這個(gè)接口的時(shí)候回重寫其中的一下方法:

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
    
}

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


簡單說一下上述三種方法的作用
onPageScrollStateChanged(int arg0) 伯诬,此方法是在狀態(tài)改變的時(shí)候調(diào)用晚唇,其中arg0這個(gè)參數(shù)
有三種狀態(tài)(0,1盗似,2)哩陕。arg0 ==1的正在滑動(dòng),arg0==2的滑動(dòng)完畢了,arg0==0的什么都沒做悍及。
當(dāng)頁面開始滑動(dòng)的時(shí)候闽瓢,三種狀態(tài)的變化順序?yàn)椋?,2心赶,0)

onPageScrolled(int arg0,float arg1,int arg2) 扣讼,當(dāng)頁面在滑動(dòng)的時(shí)候會(huì)調(diào)用此方法,在滑動(dòng)被停止之前园担,此方法回一直得到
調(diào)用届谈。其中三個(gè)參數(shù)的含義分別為:
arg0 :當(dāng)前頁面,及你點(diǎn)擊滑動(dòng)的頁面
arg1:當(dāng)前頁面偏移的百分比
arg2:當(dāng)前頁面偏移的像素位置

onPageSelected(int arg0) : 此方法是頁面跳轉(zhuǎn)完后得到調(diào)用弯汰,arg0是你當(dāng)前選中的頁面的Position(位置編號)艰山。


ViewPager更多的時(shí)候會(huì)與Fragment一起使用。Android提供了一些專門的適配器來讓ViewPager與Fragment一起工作咏闪,也就是FragmentPagerAdapter與FragmentStatePagerAdapter曙搬。他們基本上可以滿足大部分常見的需求?
在大部分時(shí)候,項(xiàng)目中的ViewPager會(huì)和Fragment同時(shí)出現(xiàn)鸽嫂,每一個(gè)ViewPager的頁面就是一個(gè)Fragment(微信主頁)?Android提供了一些專門的適配器來讓ViewPager與Fragment一起工作纵装,也就是FragmentPagerAdapter與FragmentStatePagerAdapter。

FragmentPagerAdapter繼承自PagerAdapter 据某,主要用來展示多個(gè)Fragment頁面橡娄,并且每一個(gè)Fragment都會(huì)被保存在fragment manager中。
FragmentPagerAdapter最適用于那種少量且相對靜態(tài)的頁面癣籽,例如幾個(gè)tab頁挽唉。每一個(gè)用戶訪問過的fragment都會(huì)被保存在內(nèi)存中對于較多的頁面集合,更推薦使用FragmentStatePagerAdapter筷狼。

FragmentStatePagerAdapter繼承自PagerAdapter瓶籽,主要使用Fragment來管理每個(gè)頁面。這個(gè)類同樣用來保存和恢復(fù)fragment頁面的狀態(tài)埂材。
FragmentStatePagerAdapter更多用于大量頁面塑顺,例如視圖列表。當(dāng)某個(gè)頁面對用戶不再可見時(shí)俏险,他們的整個(gè)fragment就會(huì)被銷毀严拒,僅保留fragment狀態(tài)。相比于FragmentPagerAdapter竖独,這樣做的好處是在訪問各個(gè)頁面時(shí)能節(jié)約大量的內(nèi)存開銷糙俗,但代價(jià)是在頁面切換時(shí)會(huì)增加非常多的開銷。
FragmentPagerAdapter與FragmentStatePagerAdapter存在著大量相似之處预鬓,用法也差不多巧骚,他們之間最大的不同在于:用戶訪問過的頁面不可見之后是否會(huì)保留在內(nèi)存中赊颠,而這個(gè)區(qū)別也構(gòu)成了他們使用場景的不同。


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:跳轉(zhuǎn)到不同界面 
 */  
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中需要的數(shù)據(jù)  
    // 使用SharedPreferences來記錄程序的使用次數(shù)  
    SharedPreferences preferences = getSharedPreferences(  
            SHAREDPREFERENCES_NAME, MODE_PRIVATE);  

    // 取得相應(yīng)的值劈彪,如果沒有該值竣蹦,說明還未寫入,用true作為默認(rèn)值  
    isFirstIn = preferences.getBoolean("isFirstIn", true);  

    // 判斷程序與第幾次運(yùn)行沧奴,如果是第一次運(yùn)行則跳轉(zhuǎn)到引導(dǎo)界面痘括,否則跳轉(zhuǎn)到主界面  
    if (!isFirstIn) {  
        // 使用Handler的postDelayed方法,3秒后執(zhí)行跳轉(zhuǎn)到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引導(dǎo)界面


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;  

// 底部小點(diǎn)圖片  
private ImageView[] dots;  

// 記錄當(dāng)前選中位置  
private int currentIndex;  

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

    // 初始化頁面  
    initViews();  

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

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

    views = new ArrayList<View>();  
    // 初始化引導(dǎo)圖片列表  
    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);  
    // 綁定回調(diào)  
    vp.setOnPageChangeListener(this);  
}  

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

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

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

    currentIndex = 0;  
    dots[currentIndex].setEnabled(false);// 設(shè)置為白色滔吠,即選中狀態(tài)  
}  

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;  
}  

// 當(dāng)滑動(dòng)狀態(tài)改變時(shí)調(diào)用  
@Override  
public void onPageScrollStateChanged(int arg0) {  
}  

// 當(dāng)當(dāng)前頁面被滑動(dòng)時(shí)調(diào)用  
@Override  
public void onPageScrolled(int arg0, float arg1, int arg2) {  
}  

// 當(dāng)新的頁面被選中時(shí)調(diào)用  
@Override  
public void onPageSelected(int arg0) {  
    // 設(shè)置底部小點(diǎn)選中狀態(tài)  
    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) {  
}  

// 獲得當(dāng)前界面數(shù)  
@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) {  
                // 設(shè)置已經(jīng)引導(dǎo)  
                setGuided();  
                goHome();  

            }  

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

private void goHome() {  
    // 跳轉(zhuǎn)  
    Intent intent = new Intent(activity, MainActivity.class);  
    activity.startActivity(intent);  
    activity.finish();  
}  
/** 
 *  
 * method desc:設(shè)置已經(jīng)引導(dǎo)過了,下次啟動(dòng)不用再次引導(dǎo) 
 */  
private void setGuided() {  
    SharedPreferences preferences = activity.getSharedPreferences(  
            SHAREDPREFERENCES_NAME, Context.MODE_PRIVATE);  
    Editor editor = preferences.edit();  
    // 存入數(shù)據(jù)  
    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

所以總結(jié)一下翰舌,我們可以使用ViewPager做什么:
1.程序使用導(dǎo)航,外加底部圓點(diǎn)的效果冬骚,這個(gè)在微信示例里介紹了
2.頁卡滑動(dòng)椅贱,加上菜單的效果,不管是之前的支持手勢也支持底部圖標(biāo)點(diǎn)擊的微信只冻,還是今天的微博庇麦。


相互學(xué)習(xí),共同努力喜德!
微信號:romance-l

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末山橄,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子舍悯,更是在濱河造成了極大的恐慌航棱,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贱呐,死亡現(xiàn)場離奇詭異丧诺,居然都是意外死亡入桂,警方通過查閱死者的電腦和手機(jī)奄薇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來抗愁,“玉大人馁蒂,你說我怎么就攤上這事≈╇纾” “怎么了沫屡?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長撮珠。 經(jīng)常有香客問我沮脖,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任勺届,我火速辦了婚禮驶俊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘免姿。我一直安慰自己饼酿,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布胚膊。 她就那樣靜靜地躺著故俐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪紊婉。 梳的紋絲不亂的頭發(fā)上药版,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天,我揣著相機(jī)與錄音肩榕,去河邊找鬼刚陡。 笑死,一個(gè)胖子當(dāng)著我的面吹牛株汉,可吹牛的內(nèi)容都是我干的筐乳。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼乔妈,長吁一口氣:“原來是場噩夢啊……” “哼蝙云!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起路召,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤勃刨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后股淡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體身隐,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年唯灵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了贾铝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,163評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡埠帕,死狀恐怖垢揩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情敛瓷,我是刑警寧澤叁巨,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站呐籽,受9級特大地震影響锋勺,放射性物質(zhì)發(fā)生泄漏蚀瘸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一庶橱、第九天 我趴在偏房一處隱蔽的房頂上張望苍姜。 院中可真熱鬧,春花似錦悬包、人聲如沸衙猪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽垫释。三九已至,卻和暖如春撑瞧,著一層夾襖步出監(jiān)牢的瞬間棵譬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工预伺, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留订咸,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓酬诀,卻偏偏與公主長得像脏嚷,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子瞒御,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內(nèi)容

  • 作者:李旺成 時(shí)間:2016年5月3日 一父叙、PagerAdapter介紹 先看效果圖 PagerAdapter簡介...
    diygreen閱讀 82,720評論 38 309
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,527評論 25 707
  • 今天我們來一起實(shí)現(xiàn)“愛閱”首頁滑動(dòng)切換分類瀏覽閱讀的效果,并將ViewPager和TabLayout結(jié)合起來用以實(shí)...
    常思行閱讀 5,926評論 2 48
  • 這是谷歌官方給我們提供的一個(gè)兼容低版本安卓設(shè)備的軟件包肴裙,里面包囊了只有在安卓3.0以上可以使用的api趾唱。而view...
    Ten_Minutes閱讀 5,733評論 1 19
  • 干燥的泥土擊成了點(diǎn) 烏云拐走了太陽 告訴了狂風(fēng) 狂風(fēng)酒醉亂舞 失了心智 驟雨忙碌照料 忘了本職 泥土欲睡的哈欠聽到...
    打不敗的神魔閱讀 105評論 0 0