在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Android/ 第十七章-ViewPager切換界面
第十八章-ViewPager+FragmentStatePagerAdapter實(shí)現(xiàn)仿微信Tab
第十五章-GridView實(shí)現(xiàn)動態(tài)添加和刪除子項(xiàng)
第九章-進(jìn)度條ProgressBar
第十二章-經(jīng)典的ListView
第十四章-GridView控件
第八章-時(shí)間相關(guān)控件
第七章-下拉框Spinner控件
第二章-EditText探秘
第二十章-Android菜單之上下文菜單
第十一章-各種對話框Dialog集錦
第二十一章-Android菜單之子菜單
第六章-切換類TextSwitcher和ImageSwitcher
第十七章-ViewPager切換界面
第五章-開關(guān)按鈕ToggleButton和Switch
第二十二章-PopupWindow浮動窗
第十六章-幻燈片ViewFlipper
第二十四章-RecyclerView動態(tài)添加、刪除及點(diǎn)擊事件
第三章-交互之王Button控件
第二十三章-全新控件RecyclerView
第一章-好玩的TextView
第十三章-ListView擴(kuò)展(多選、全選、反選)
第四章-玩轉(zhuǎn)單選和多選按鈕
第十章-可以拖動的ProgressBar-SeekBar
第十九章-Android菜單之選項(xiàng)菜單

第十七章-ViewPager切換界面

ViewFlipper一般僅用于圖片的展示,如果要進(jìn)行布局文件的切換就要用到ViewPager控件,其繼承結(jié)構(gòu)如下:

public class
ViewPager
extends ViewGroup
java.lang.Object
   ?    android.view.View
       ?    android.view.ViewGroup
           ?    android.support.v4.view.ViewPager

繼承自ViewGroup可以看出來是一個(gè)容器類,類前包名是android.support.v4,這是一個(gè)兼容包,注意在布局文件中引入該控件時(shí),標(biāo)簽要寫全即:< android.support.v4.view.ViewPager >。API文檔中對ViewPager進(jìn)行了描述,總結(jié)如下:

  • ViewPager類直接繼承自ViewGroup類,作為一個(gè)容器類,可以向其中添加Viewl類
  • 數(shù)據(jù)源和顯示之間需要一個(gè)適配器類PagerAdapter進(jìn)行適配
  • ViewPager經(jīng)常和Fragemnet一起使用,并且提供專門的適配器類FragmentPagerAdapter和FragmentStatePagerAdapter類供開發(fā)者調(diào)用。

實(shí)現(xiàn)PageAdapter必須實(shí)現(xiàn)四個(gè)方法,這里進(jìn)行介紹:

  • public Object instantiateItem(ViewGroup container, int position) :初始化一個(gè)子View
  • public void destroyItem(ViewGroup container, int position,Object object):銷毀一個(gè)子View
  • public int getCount():返回子View的個(gè)數(shù)
  • public boolean isViewFromObject(View arg0, Object arg1):返回一個(gè)布爾型變量,判斷子View是否來自O(shè)bject。 主布局文件(activity_main.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/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

注意,標(biāo)簽內(nèi)需要填入包.類名,否則會報(bào)錯(cuò)。 子布局文件(view1.xml)

<?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">
    <TextView
        android:layout_width="match_parent"
        android:gravity="center"
        android:text="頁面1"
        android:textSize="30sp"
        android:layout_height="match_parent" />
</LinearLayout>

一共有三個(gè)子View文件作為演示,每個(gè)子View中都包含一個(gè)TextView,由于只是text屬性的不同,這里僅貼出view1的代碼。 適配器類(MyViewPagerAdapter.java)

public class MyViewPagerAdapter extends PagerAdapter {
    private List<View> datas;
   public  MyViewPagerAdapter(List<View> datas ){
       this.datas=datas;
   }
    @Override
    public int getCount() {//返回頁卡數(shù)量
        return datas.size();
    }
    @Override
    public boolean isViewFromObject(View view, Object object) {//判斷View是否來自O(shè)bject
        return view==object;
    }
    @Override
    public Object instantiateItem(ViewGroup container, int position) {//初始化一個(gè)頁卡
         container.addView(datas.get(position));
        return datas.get(position);
    }
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {//銷毀一個(gè)頁卡
        container.removeView(datas.get(position));
    }
}

自定義適配器類MyViewPagerAdapter繼承自PagerAdapter,編寫了構(gòu)造函數(shù),用于傳入datas數(shù)據(jù)集。此外,覆寫了四個(gè)必須要覆寫的方法,這四個(gè)方法的含義參照注釋。 (MainActivity.java)

public class MainActivity extends Activity {
    private ViewPager viewPager;
    private List<View> datas;
    private MyViewPagerAdapter myViewPagerAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        viewPager=(ViewPager)findViewById(R.id.viewPager);
        initDatas();//初始化數(shù)據(jù)集
        myViewPagerAdapter=new MyViewPagerAdapter(datas);
        viewPager.setAdapter(myViewPagerAdapter);//設(shè)置適配器
    }
    private void initDatas() {
        datas=new ArrayList<>();
        View view1= LayoutInflater.from(this).inflate(R.layout.view1,null);
        View view2= LayoutInflater.from(this).inflate(R.layout.view2,null);
        View view3= LayoutInflater.from(this).inflate(R.layout.view3,null);
        datas.add(view1);
        datas.add(view2);
        datas.add(view3);
    }
}

總結(jié)一下,PagerView的實(shí)現(xiàn)可以分為三個(gè)步驟:

  1. 準(zhǔn)備數(shù)據(jù)源(initDatas)
  2. 準(zhǔn)備適配器類并初始化(MyViewPagerAdapter)
  3. 設(shè)置適配器(setAdapter)

運(yùn)行實(shí)例如下:

http://wiki.jikexueyuan.com/project/twenty-four-Scriptures/images/17-1.png" alt="這里寫圖片描述" />

http://wiki.jikexueyuan.com/project/twenty-four-Scriptures/images/17-2.png" alt="這里寫圖片描述" />

這時(shí),左右滑動屏幕就可以切換不同的View了,下面我們看一下如何添加頂部或底部導(dǎo)航,Android提供了兩種方式供我們選擇,分別是PagerTitleStrip和PagerTabStrip,下面分別研究一下兩者的異同點(diǎn)。

  • PagerTitleStrip API中這么定義:是一個(gè)非交互的當(dāng)前頁面指示器,一般指示ViewPager中的前一頁、當(dāng)前頁和下一頁三個(gè)頁面??梢酝ㄟ^PagerTitleStrip標(biāo)簽添加到xml布局當(dāng)中。我們可以設(shè)置layout_gravity屬性為TOP或者BOTTOM來決定在頁面頂部或者底部顯示,添加PagerTitleStrip要在適配器中覆寫getPageTitle方法。 上面是抽象的理論描述,下面通過一個(gè)實(shí)例來看一下如何在ViewPager中添加PagerTitleStrip控件。

主布局文件(activity_main.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/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <android.support.v4.view.PagerTitleStrip
            android:id="@+id/pagerTitleStrip"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        </android.support.v4.view.PagerTitleStrip>
    </android.support.v4.view.ViewPager>
</RelativeLayout>

PagerTitleStrip標(biāo)簽也要設(shè)置全路徑,并放在ViewPager標(biāo)簽內(nèi),默認(rèn)沒有添加layout_gravity屬性,標(biāo)簽顯示在頁面頂部,若想設(shè)置在底部,添加這一屬性設(shè)置其值為BOTTOM即可。 適配器類(MyViewPagerAdapter.java)

public class MyViewPagerAdapter extends PagerAdapter {
    private List<View> datas;
    private List<String> titles;
   public  MyViewPagerAdapter(List<View> datas,List<String> titles ){
       this.datas=datas;
       this.titles=titles;
   }
    @Override
    public int getCount() {//返回頁卡數(shù)量
        return datas.size();
    }
    @Override
    public boolean isViewFromObject(View view, Object object) {//判斷View是否來自O(shè)bject
        return view==object;
    }
    @Override
    public Object instantiateItem(ViewGroup container, int position) {//初始化一個(gè)頁卡
         container.addView(datas.get(position));
        return datas.get(position);
    }
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {//銷毀一個(gè)頁卡
        container.removeView(datas.get(position));
    }
    @Override
    public CharSequence getPageTitle(int position) {
        return titles.get(position);
    }
}

為了方便觀察,較上一個(gè)實(shí)例增加或修改的代碼部分進(jìn)行了加粗,首先是修改了構(gòu)造方法,多傳入了一個(gè)標(biāo)題的數(shù)據(jù)集,然后覆寫了一個(gè)getPagerTitle的方法,這個(gè)方法可以根據(jù)position參數(shù)返回對應(yīng)的title。

MainActivity(MainActivity.java)

public class MainActivity extends Activity {
    private ViewPager viewPager;
    private PagerTitleStrip pagerTitleStrip;
    private List<View> datas;
    private List<String> titles;
    private MyViewPagerAdapter myViewPagerAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        viewPager=(ViewPager)findViewById(R.id.viewPager);
      pagerTitleStrip=(PagerTitleStrip)findViewById(R.id.pagerTitleStrip);
        initDatas();
        myViewPagerAdapter=new MyViewPagerAdapter(datas,titles);
        viewPager.setAdapter(myViewPagerAdapter);
    }
    private void initDatas() {
        datas=new ArrayList<>();
        titles=new ArrayList<>();
        View view1= LayoutInflater.from(this).inflate(R.layout.view1,null);
        View view2= LayoutInflater.from(this).inflate(R.layout.view2,null);
        View view3= LayoutInflater.from(this).inflate(R.layout.view3,null);
        datas.add(view1);
        datas.add(view2);
        datas.add(view3);
        titles.add("第一頁");
        titles.add("第二頁");
        titles.add("第三頁");
    }
}

較上一個(gè)實(shí)例來講,這里添加了一個(gè)標(biāo)題的數(shù)據(jù)集titles,初始化MyViewPagerAdapter的時(shí)候傳入了兩個(gè)參數(shù),頁面布局?jǐn)?shù)據(jù)集(datas)和標(biāo)題數(shù)據(jù)集(titles)。 運(yùn)行實(shí)例如下:

http://wiki.jikexueyuan.com/project/twenty-four-Scriptures/images/17-3.png" alt="這里寫圖片描述" />

點(diǎn)擊頂部的標(biāo)題欄,不會進(jìn)行頁面切換,正如API文檔里描述的那樣-non-interactive indicator,只能作為一個(gè)頁面指示器,不具有交互作用,下面我們共同來實(shí)踐一下具有交互效果的PagerTabStrip。

  • PagerTabStrip API中這么描述PagerTabStrip:

PagerTabStrip is an interactive indicator of the current, next, and previous pages of a ViewPager. It is intended to be used as a child view of a ViewPager widget in your XML layout. Add it as a child of a ViewPager in your layout file and set its android:layout_gravity to TOP or BOTTOM to pin it to the top or bottom of the ViewPager. The title from each page is supplied by the method getPageTitle(int) in the adapter supplied to the ViewPager.

For a non-interactive indicator, see PagerTitleStrip. 這里把英文的API文檔貼出來,帶領(lǐng)大家大致翻譯一下:PagerTabStrip是一個(gè)關(guān)于當(dāng)前頁、下一頁和上一頁可交互的頁面指示器。作為一個(gè)子View布局在ViewPager控件內(nèi)部。同時(shí),也可以通過設(shè)置layout_gravity屬性為TOP或BOTTOM來決定顯示在頁面頂部或底部。每個(gè)頁面標(biāo)題是通過適配器類中覆寫getPageTitle方法提供給ViewPager的。最后一句也點(diǎn)明了,若要使用一個(gè)非交互指示器,可以參考PagerTitleStrip。

從API文檔上可以看出,兩個(gè)方式使用方法一樣,因此,這里只要在布局文件中更換一下標(biāo)簽如下:

<?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/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <android.support.v4.view.PagerTabStrip
            android:id="@+id/pagerTabStrip"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        </android.support.v4.view.PagerTabStrip>
    </android.support.v4.view.ViewPager>
</RelativeLayout>

將標(biāo)簽換成android.support.v4.view.PagerTabStrip。 MainActivity.java中,將PagerTitleStrip換成PagerTabStrip即可,其余代碼不變:

private PagerTabStrip pagerTabStrip= (PagerTabStrip)findViewById(R.id.pagerTabStrip);

運(yùn)行實(shí)例如下:

http://wiki.jikexueyuan.com/project/twenty-four-Scriptures/images/17-4.png" alt="這里寫圖片描述" />

點(diǎn)擊頂部指示頁,可以進(jìn)行頁面切換,除此之外,較PagerTitleStrip而言,PagerTabStrip當(dāng)前頁的下面還多了一個(gè)小橫標(biāo),以上功能基本實(shí)現(xiàn)了,下面來研究一下,如何讓外觀變得更漂亮,Android也給我們提供了一些方法用于改變指示欄的樣式。常用方法參考下表:

http://wiki.jikexueyuan.com/project/twenty-four-Scriptures/images/17-5.png" alt="這里寫圖片描述" />

在MainActivity.java的onCreate方法中加入如下代碼:

pagerTabStrip.setDrawFullUnderline(false);//取消標(biāo)題欄子View之間的分割線
pagerTabStrip.setTabIndicatorColor(Color.WHITE);//改變指示器顏色為白色
pagerTabStrip.setTextColor(Color.WHITE);//該變字體顏色為白色
pagerTabStrip.setBackgroundResource(android.R.drawable.alert_dark_frame);//設(shè)置標(biāo)題欄背景圖片

再次運(yùn)行實(shí)例如下:

http://wiki.jikexueyuan.com/project/twenty-four-Scriptures/images/17-6.png" alt="這里寫圖片描述" />

上面講解了加載布局文件的ViewPager,由API文檔可知,ViewPager還可以加載Fragment控件,也有兩個(gè)適配器類(FragmentPagerAdapter和FragmentStatePagerAdapter)可以實(shí)現(xiàn),下面分別實(shí)現(xiàn)并介紹相關(guān)異同點(diǎn)。

  • FragmentPagerAdapter實(shí)現(xiàn)
public abstract class
FragmentPagerAdapter
extends PagerAdapter
java.lang.Object
   ?    android.support.v4.view.PagerAdapter
       ?    android.support.v4.app.FragmentPagerAdapter

由繼承結(jié)構(gòu)可以看出FragmentPagerAdapter繼承自PagerAdapter,子頁面由Fragment組成,該適配器沒有實(shí)現(xiàn)頁面銷毀的方法,所有的頁面都保存在內(nèi)存當(dāng)中,當(dāng)頁面比較大時(shí)要考慮使用FragmentStatePagerAdapter適配器類。 實(shí)現(xiàn)FragmentPagerAdapter時(shí)必須要覆寫的方法是getItem和getCount方法。

下面通過一個(gè)實(shí)例進(jìn)行實(shí)現(xiàn),分三個(gè)步驟實(shí)現(xiàn):

  • 準(zhǔn)備Fragment的數(shù)據(jù)集
  • 編寫適配器類
  • 初始化數(shù)據(jù)集,設(shè)置適配器 Fragment代碼(MyFragment1.java)
public class MyFragment1 extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.view1,null);
    }
}

Fragment中只覆寫了onCreateView方法,其他兩個(gè)Fragment差別只是載入了不同的view,這里就不再貼出。

適配器類代碼(MyFragmentViewPagerAdapter.java)

public class MyFragmentViewPagerAdapter extends FragmentPagerAdapter{
   private  List<Fragment> datas;
    private List<String> titles;
    public MyFragmentViewPagerAdapter(FragmentManager fm, List<Fragment> datas,List<String> titles) {
        super(fm);
        this.titles=titles;
        this.datas=datas;
    }
    @Override
    public Fragment getItem(int position) {
        return datas.get(position);
    }
    @Override
    public int getCount() {
        return datas.size();
    }
    @Override
    public CharSequence getPageTitle(int position) {
        return titles.get(position);
    }
}

這里構(gòu)建構(gòu)造方法時(shí)傳入了FragmentManager參數(shù),并傳入了Fragment類的數(shù)據(jù)集合String型的標(biāo)題集。必須要覆寫的方法只有g(shù)etI tem(獲取子項(xiàng))和getCount(獲取子項(xiàng)個(gè)數(shù))兩個(gè)。為了顯示標(biāo)題欄,這里覆寫了getPageTitle方法。

MainActivity(MainActivity.java)

public class MainActivity extends FragmentActivity {
    private ViewPager viewPager;
    private PagerTabStrip pagerTabStrip;
    private List<Fragment> datas;//數(shù)據(jù)源
    private List<String> titles;
    private MyFragmentViewPagerAdapter myFragmentViewPagerAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        viewPager=(ViewPager)findViewById(R.id.viewPager);
        pagerTabStrip=(PagerTabStrip)findViewById(R.id.pagerTabStrip);
        pagerTabStrip.setDrawFullUnderline(false);//取消標(biāo)題欄和子View直接的分割線
        pagerTabStrip.setTabIndicatorColor(Color.WHITE);
        pagerTabStrip.setTextColor(Color.WHITE);
        pagerTabStrip.setBackgroundResource(android.R.drawable.alert_dark_frame);
        initDatas();
        myFragmentViewPagerAdapter=new MyFragmentViewPagerAdapter(getSupportFragmentManager(),datas,titles);
        viewPager.setAdapter(myFragmentViewPagerAdapter);
    }
    private void initDatas() {
        datas=new ArrayList<>();
        titles=new ArrayList<>();
        datas.add(new MyFragment1());
        datas.add(new MyFragment2());
        datas.add(new MyFragment3());
        titles.add("第一頁");
        titles.add("第二頁");
        titles.add("第三頁");
    }
}

初始化數(shù)據(jù)源時(shí),加入的是Fragment對象,初始化適配器類MyFragmentViewPagerAdapter時(shí)要傳入FragmentManager對象,這里使用getSupportFragmentManager方法獲取,不過,要注意這時(shí)MainActivity要繼承自FragmentActivity,才好調(diào)用這個(gè)方法。 運(yùn)行實(shí)例如下:

http://wiki.jikexueyuan.com/project/twenty-four-Scriptures/images/17-7.png" alt="這里寫圖片描述" />

運(yùn)行效果和PagerAdapter類實(shí)現(xiàn)的一樣。

  • FragmentStatePagerAdapter實(shí)現(xiàn) 同樣也是繼承自PagerAdapter,此適配器更適用于大量頁面的情形,因?yàn)椴槐伙@示的頁面會被回收,可以大大降低內(nèi)存的使用率。在使用FragmentStatePagerAdapter作為適配器時(shí),其余都不用改動,只要覆寫instantiateItem(初始化子頁面)和destroyItem(銷毀子頁面)兩個(gè)方法即可。如下:
@Override
public Object instantiateItem(ViewGroup container, int position) {
    return super.instantiateItem(container, position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    super.destroyItem(container, position, object);
}

此方式可以銷毀不可見的頁面(不在標(biāo)題欄中的頁面,標(biāo)題欄中一般存在三個(gè)頁面),回收內(nèi)存,在實(shí)際開發(fā)中推薦使用。 ViewPager控件提供了頁面切換時(shí)的事件監(jiān)聽,下面就在MainActivity中實(shí)現(xiàn)一下:

public class MainActivity extends FragmentActivity implements ViewPager.OnPageChangeListener{
    private ViewPager viewPager;
    private PagerTabStrip pagerTabStrip;
    private List<Fragment> datas;
    private List<String> titles;
    private MyFragmentViewPagerAdapter myFragmentViewPagerAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        viewPager=(ViewPager)findViewById(R.id.viewPager);
        pagerTabStrip=(PagerTabStrip)findViewById(R.id.pagerTabStrip);
        pagerTabStrip.setDrawFullUnderline(false);//取消標(biāo)題欄和子View直接的分割線
        pagerTabStrip.setTabIndicatorColor(Color.WHITE);
        pagerTabStrip.setTextColor(Color.WHITE);
        pagerTabStrip.setBackgroundResource(android.R.drawable.alert_dark_frame);
        initDatas();
        myFragmentViewPagerAdapter=new MyFragmentViewPagerAdapter(getSupportFragmentManager(),datas,titles);
        viewPager.setAdapter(myFragmentViewPagerAdapter);
        viewPager.setOnPageChangeListener(this);
    }
    private void initDatas() {
        datas=new ArrayList<>();
        titles=new ArrayList<>();
        datas.add(new MyFragment1());
        datas.add(new MyFragment2());
        datas.add(new MyFragment3());
        titles.add("第一頁");
        titles.add("第二頁");
        titles.add("第三頁");
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {
        Toast.makeText(MainActivity.this,"當(dāng)前是第:"+(position+1)+"頁",Toast.LENGTH_SHORT).show();

    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }
}

實(shí)現(xiàn)了onPageChangeListener接口,需要覆寫三個(gè)方法:

  • void onPageScrolled(int position, float positionOffset, int positionOffsetPixels):頁面滾動時(shí)觸發(fā);
  • void onPageSelected(int position):頁面選擇時(shí)觸發(fā);
  • void onPageScrollStateChanged(int state):頁面滾動狀態(tài)切換時(shí)觸發(fā);

在頁面選擇觸發(fā)的方法里通過position參數(shù)獲得當(dāng)前頁面信息,然后由Toast輸出信息。

運(yùn)行實(shí)例如下:

http://wiki.jikexueyuan.com/project/twenty-four-Scriptures/images/17-8.png" alt="這里寫圖片描述" />

切換頁面后會Toast出當(dāng)前所在頁。