软件世界网 购物 网址 三丰软件 | 小说 美女秀 图库大全 游戏 笑话 | 下载 开发知识库 新闻 开发 图片素材
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
移动开发 架构设计 编程语言 Web前端 互联网
开发杂谈 系统运维 研发管理 数据库 云计算 Android开发资料
  软件世界网 -> 移动开发 -> AndroidUI学习笔记之使用ViewPager实现导航 -> 正文阅读

[移动开发]AndroidUI学习笔记之使用ViewPager实现导航


[img]http://1.bp.blogspot.com/-XXHZWRuWzeY/T-XrchtZQ4I/AAAAAAAADt8/a7_XBJhAWFc/s1600/ViewPager_02.png
ViewPager的用处就如上图所示(图源网络),当我们左右滑动屏幕时,会从一个页卡转到下一个页卡。
ViewPager中默认三个为一组的加载,例如,view1  view2   view3,当我们向左滑动时,view1会被销毁,
而view4(如果有的话)就会实例化加载进来,变成view2  view3   view4的样子。
使用ViewPager大致分为以下步骤:
建立数据源List<View>或者List<Fragment>。
将数据源绑定到适配器,不同的数据源有不同的适配器。
再将适配器绑定到当前的ViewPager中,完成。
当填充的内容不同时,使用的适配器也不同。
PagerAdapter适配器对应的数据源是List<View>,能动态加载页卡,销毁页卡。
FragmentPagerAdapter适配器对应的数据源是List<Fragment>,不能动态加载页卡,销毁页卡,一次性全部导入。
FragmentStatePagerAdapter适配器对应的数据源是List<Fragment>,能动态加载页卡,销毁页卡。
建立数据源List<View>或者List<Fragment>。
ViewPager中可以填充View和Fragment作为页卡。
我们这里以View为例,先新建一个简单的layout,里面只有一个TextView,用来显示第几个页卡。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/pageText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"  />
</LinearLayout>
然后在Activity中将这个layout转换为View对象,有两种方法,这里大致提一下。
//第一种方法
LayoutInflater lf = getLayoutInflater().from(this);//先获取LayoutInflater 对象
lf.inflate(resource, root);//再inflate获取view,resource表示layout的布局文件,root表示需要附加到resource资源文件的根控件

//第二种方法
View.inflate(context, resource, root);//context表示当前的上下文,resouce和root参照上面解释
//这里的root就是说要把layout转换得到的view加载到哪一个ViewGroup里面,我们这里不需要.所以设置为null
得到的view在添加到List集合里面,这样第一步建立数据源就完成了。
    viewList = new ArrayList<View>();
    for (int i = 0; i < 4; i++) {
        View view = View.inflate(MainActivity.this, R.layout.view, null);
        ((TextView) view.findViewById(R.id.pageText)).setText("这是第" + i + "个View");
        viewList.add(view);
    }

将数据源绑定到适配器,不同的数据源有不同的适配器。
我们需要自己来写一个适配器,因为之前用的是View来填充的,所以这里使用PagerAdapter。
public class MyViewPagerAdapter extends PagerAdapter {
    List<View> viewList;//页卡的View集合
    List<String> titleList;//页卡的标题集合

    public MyViewPagerAdapter(List<View> viewList, List<String> titleList) {//自定义的构造方法
        this.viewList = viewList;
        this.titleList = titleList;
    }
    @Override
    public int getCount() {
        return viewList.size();//返回页卡数量
    }
    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view==object;//这个view是否来自object的类型
    }
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        container.addView(viewList.get(position));//实例化一个页卡,左右滑动时调用
        return viewList.get(position);
    }
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView(viewList.get(position));//销毁一个页卡,左右滑动时调用
    }
    @Override
    public CharSequence getPageTitle(int position) {
        return titleList.get(position);//设置页卡的标题,如上图中的FragmentA,FragmentB,FragmentC
    }
}

里面有一些常用的方法要重写。
  1. getCount()返回的是页卡的数量,也就是你填充进去的View的数量,我们用集合的size()方法返回一个int。
  2. isViewFromObject()判断的是view的类型,有时候我们要判断这个view是否为TextView或者Button之类的。
  3. instantiateItem()这个方法的用法,就是当页面是view1 view2 view3时,向左滑动,出现view4的时候调用的,用来加载view4,形成view2 view3 view4。
  4. destroyItem()和上一个方法同时调用,销毁view1,本质上就是从ViewGroup中删掉view1,加入view4。
  5. getPageTitle()显示的是标题,如最上面图中的fragmengA,fragmengB,fragmengC。

我们写了个适配器之后,之后当然就是加载数据源了。
第二步的主要工作就是写适配器了。
myViewPagerAdapter = new MyViewPagerAdapter(viewList, titleList);//将List<View>传入,适配器中要写构造方法

再将适配器绑定到当前的ViewPager中,完成。

先在Activity的XML布局文件中,加入ViewPager。
实现上图中的FragmentA,FragmentB,FragmentC的标题其实有两种方法,
使用PagerTabStrip或者PagerTitleStrip两种,注意只能取其中一种方法。
然后通过layout_gravity来布置,我们把tab放在顶部,title放在底部。
<android.support.v4.view.ViewPager
    android:id="@+id/viewPager"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center">
    <android.support.v4.view.PagerTabStrip
        android:id="@+id/tab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:background="@color/yellow"  >
    </android.support.v4.view.PagerTabStrip>
    <android.support.v4.view.PagerTitleStrip
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:background="@color/blue"    >
    </android.support.v4.view.PagerTitleStrip>
</android.support.v4.view.ViewPager>
会造成tab的失效(PagerTabStripPagerTitleStrip的子类,有兴趣的可以看下API)
然后绑定适配器,完成。
viewPager = (ViewPager) findViewById(R.id.viewPager);
viewPager.setAdapter(myViewPagerAdapter);

附加:
如果觉得样式很丑的话,我们可以自定义样式
建议还是实际写一下代码,增加印象。
//在pagerTabStrip中有以下方法
pagerTabStrip.setBackgroundColor(int color);//导航栏的背景色
pagerTabStrip.setTextColor(int color);//导航栏的文字色
pagerTabStrip.setDrawFullUnderline(boolean drawFull);//导航栏底线是否显示
pagerTabStrip.setTabIndicatorColor(int color);//当前页卡的选中的线的颜色

如果不是用View,而是用Fragment填充呢
通过查阅API,我们可以知道FragmentPagerAdapterFragmentStatePagerAdapter兄弟关系,都是直接继承PagerAdapter
两者的区别在于FragmentPagerAdapter不能动态加载页卡,是一次性导入所有页卡,而FragmentStatePagerAdapter是和PagerAdapter一样动态加载页卡的。
和View一样,我们为FragmentPagerAdapter适配器添加数据源List<Fragment>,然后重写FragmentPagerAdapter中的方法(继承自PagerAdapter)。
注意FragmentPagerAdapter是一次性加载所有页卡,所以不用重写instantiateItem()和destroyItem()(这两个方法在FragmentStatePagerAdapter要重写)。
值得注意的是我们需要import android.support.v4.app.Fragment;而不是import android.app.Fragment。
并且,我们的Activity要继承自FragmentActivity,
并且在new对象的时候,要在Activity中用getSupportFragmentManager()获取FragmentManager对象。
public MyFragmentPagerAdapter(FragmentManager fm,List<Fragment> fragmentList, List<String> titleList) {
        super(fm);
        this.fragmentList = fragmentList;
        this.titleList = titleList;
    }

最后,我们再添加一个监听器
public class MainActivity extends FragmentActivity implements ViewPager.OnPageChangeListener{
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        System.out.println("当前是第"+position+"个页卡" +
                ",当前页面偏移的百分比:"+positionOffset+
                ",当前页面偏移的像素位置:"+positionOffsetPixels);
        //当页卡滚动时调用该方法
    }

    @Override
    public void onPageSelected(int position) {
        Toast.makeText(MainActivity.this, "当前是第"+position+"个页卡", Toast.LENGTH_SHORT).show();
        //当页卡改变时调用该方法
    }

    @Override
    public void onPageScrollStateChanged(int state) {
        switch (state) {
            case 0: Toast.makeText(MainActivity.this, "滑动完毕", Toast.LENGTH_SHORT).show();break;
            case 1: Toast.makeText(MainActivity.this, "手指按下", Toast.LENGTH_SHORT).show();break;
            case 2: Toast.makeText(MainActivity.this, "手指抬起", Toast.LENGTH_SHORT).show();break;
        }
        //当滑动状态改变时调用该方法
    }

以下附上以View填充的ViewPager的Demo源码。
public class MainActivity extends Activity implements ViewPager.OnPageChangeListener{
    List<View> viewList;//填充View数据源
    List<String> titleList;//View的标题集合
    MyViewPagerAdapter myViewPagerAdapter;//自定义的以View为数据源的适配器
    PagerTabStrip pagerTabStrip;//导航栏
    ViewPager viewPager;//被填充的组件
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        viewList = new ArrayList<View>();
        titleList = new ArrayList<String>();
        View[] views = new View[4];
        for (int i = 0; i < 4; i++) {
            views[i] = View.inflate(MainActivity.this, R.layout.view, null);//将view.xml转化为View对象
            ((TextView) views[i].findViewById(R.id.pageText)).setText("这是第" + i + "个View");
            titleList.add("第" + i + "页");//添加标题到集合
            viewList.add(views[i]);//添加view到集合
        }

        pagerTabStrip = (PagerTabStrip) findViewById(R.id.tab);//自定义导航栏样式
        pagerTabStrip.setBackgroundColor(Color.YELLOW);//导航栏背景色
        pagerTabStrip.setTextColor(Color.BLUE);//导航栏文字色
        pagerTabStrip.setDrawFullUnderline(false);//导航栏底线是否显示
        pagerTabStrip.setTabIndicatorColor(Color.RED);//导航栏选中的当前页卡的底线颜色

        myViewPagerAdapter = new MyViewPagerAdapter(viewList, titleList);
        viewPager = (ViewPager) findViewById(R.id.viewPager);
        viewPager.setAdapter(myViewPagerAdapter);//添加适配器到ViewPager
        viewPager.setOnPageChangeListener(this);//设置监听器
    }
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        System.out.println("当前是第"+position+"个页卡" +
                ",当前页面偏移的百分比:"+positionOffset+
                ",当前页面偏移的像素位置:"+positionOffsetPixels);
        //当页卡滚动时调用该方法
    }
    @Override
    public void onPageSelected(int position) {
        Toast.makeText(MainActivity.this, "当前是第"+position+"个页卡", Toast.LENGTH_SHORT).show();
        //当页卡改变时调用该方法
    }
    @Override
    public void onPageScrollStateChanged(int state) {
        switch (state) {
            case 0: Toast.makeText(MainActivity.this, "滑动完毕", Toast.LENGTH_SHORT).show();break;
            case 1: Toast.makeText(MainActivity.this, "手指按下", Toast.LENGTH_SHORT).show();break;
            case 2: Toast.makeText(MainActivity.this, "手指抬起", Toast.LENGTH_SHORT).show();break;
        }
        //当滑动状态改变时调用该方法
    }
}
public class MyViewPagerAdapter extends PagerAdapter {
    List<View> viewList;
    List<String> titleList;
    public MyViewPagerAdapter(List<View> viewList, List<String> titleList) {
        this.viewList = viewList;
        this.titleList = titleList;
    }

    @Override
    public int getCount() {
        return viewList.size();//返回页卡数量
    }
    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view==object;//这个view是否来自object的类型
    }
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        container.addView(viewList.get(position));//实例化一个页卡
        return viewList.get(position);
    }
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView(viewList.get(position));//销毁一个页卡
    }
    @Override
    public CharSequence getPageTitle(int position) {
        return titleList.get(position);//设置页卡的标题
    }
}
<!--主Activity的XML布局-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:orientation="vertical">

    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center">
        <android.support.v4.view.PagerTabStrip
            android:id="@+id/tab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:background="@color/yellow"
            >
        </android.support.v4.view.PagerTabStrip>
    </android.support.v4.view.ViewPager>
</LinearLayout>
<!--加载的View的布局-->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/pageText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
</LinearLayout>

......显示全文...
    点击查看全文


上一篇文章      下一篇文章      查看所有文章
2016-04-03 20:41:06  
移动开发 最新文章
深入了解android中的消息机制Handler
Android
Libgdx之BitmapFont字体
AndroidApp发布到应用市场的流程
Android开发找工作之前先看看这些知识点吧
View的事件分发机制解析
简单介绍了解白鹭引擎Egret
Cocos2d
android获取本地图片(二)
动画特效七:碰撞动画
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 美食菜谱 新闻资讯 电影视频 小游戏 Chinese Culture 股票 租车
生肖星座 三丰软件 视频 开发 短信 中国文化 网文精选 搜图网 美图 阅读网 多播 租车 短信 看图 日历 万年历 2018年1日历
2018-1-16 21:01:08
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  软件世界网 --