软件世界网 购物 网址 三丰软件 | 小说 美女秀 图库大全 游戏 笑话 | 下载 开发知识库 新闻 开发 图片素材
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
移动开发 架构设计 编程语言 Web前端 互联网
开发杂谈 系统运维 研发管理 数据库 云计算 Android开发资料
  软件世界网 -> 移动开发 -> AndroidUI学习笔记之使用ViewPager实现导航 -> 正文阅读
移动开发 最新文章
深入了解android中的消息机制Handler
Android
Libgdx之BitmapFont字体
AndroidApp发布到应用市场的流程
Android开发找工作之前先看看这些知识点吧
View的事件分发机制解析
简单介绍了解白鹭引擎Egret
Cocos2d
android获取本地图片(二)
动画特效七:碰撞动画

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

  2016-04-03 20:41:55


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  
360图书馆 论文大全 母婴/育儿 软件开发资料 网页快照 文字转语音 购物精选 软件 美食菜谱 新闻中心 电影下载 小游戏 Chinese Culture
生肖星座解梦 三沣玩客 拍拍 视频 开发 Android开发 站长 古典小说 网文精选 搜图网 天下美图 中国文化英文 多播视频 装修知识库
2017-1-20 11:49:49
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  软件世界网 --