安卓开发_深入学习ViewPager控件

一、概述

ViewPager是android扩展包v4包(android.support.v4.view.ViewPager)中的类,这个类可以让用户左右切换当前的view。

ViewPager特点:

1)ViewPager类直接继承了ViewGroup类,所以它是一个容器类,可以在其中添加其他的view类。

2)ViewPager类需要一个PagerAdapter适配器类(通常需要自定义适配器继承PagerAdapter类重写其中的方法)给它提供数据。

3)ViewPager经常和Fragment一起使用,并且提供了专门的FragmentPagerAdapter和FragmentStatePagerAdapter类供Fragment中的ViewPager使用。

二、关键方法

setCurrentItem(int position)           显示第position页的View(界面)
setAdapter() 设置ViewPager的适配器,参数为是适配器
setOnPageChangeListener() 设置页面改变事件监听事件
setOffscreenPageLimit(int limit) 设置脱离屏幕的页面限制--最多同时显示的页面数

三、适配器

ViewPager相关适配器:

1、PagerAdapter  需要重写getCount(),isViewFromObject()方法,添加instantiateItem(),destroyItem()方法

2、FragmentPagerAdapter和FragmentStatePagerAdapter

区别:

FragmentPagerAdapter  //这个适配器当前fragment(正在显示的)和其他fragment(a)(未显示的)间隔超过一个fragment的距离,则销毁fragment(a)的View,fragment(a)不销毁

FragmentStatePagerAdapter //这个适配器当前fragment(正在显示的)和其他fragment(a)(未显示的)间隔超过一个fragment的距离,则销毁fragment(a)

四、通过简单的Demo学习ViewPager的使用步骤

1、在布局文件中使用<android.support.v4.view.ViewPager>标签

 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
> <android.support.v4.view.ViewPager //用于显示ViewPager
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/viewPager"
/> </FrameLayout>

2、代码中增加显示的页面(创建一个存放View的集合,向集合中添加的View就是要显示的View,比如三个界面都是ImageView),

 View views = new ArrayList<View>();
int image[] = new int[]{R.drawable.a1,R.drawable.a2,R.drawable.a3}; //这里三张图片分别是红,黄,蓝色的图片
for(int i=;i<=;i++)
{
//实例化中ViewPager中要显示的图片控件
imageView = new ImageView(getApplicationContext());
//设置图片格式
imageView.setScaleType(ScaleType.CENTER_CROP);
imageView.setImageResource(image[i-]);
views.add(imageView);
}

3、在Activity里实例化ViewPager组件,并设置它的Adapter(即PagerAdapter)

        //实例化适配器
MyPagerAdapter adapter = new MyPagerAdapter();
//设置适配器 viewPager.setAdapter(adapter); //声明PagerAdapter子类,用于管理ViewPager中显示的View控件,重写四个方法
class MyPagerAdapter extends PagerAdapter
{ @Override
public int getCount() {
// TODO Auto-generated method stub
return views.size();
} //判断当前显示的UI对象是否和数据对象一致
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
// TODO Auto-generated method stub
return arg0 == arg1;
} @Override
public Object instantiateItem(ViewGroup container, int position) {
//获得指定位置的View,并增加到ViewPager中,同时作为当前页面的数据返回
container.addView(views.get(position));
return views.get(position); } @Override
public void destroyItem(ViewGroup container, int position, Object object) {
//当前位置和ViewPager中正显示的页面的位置的间隔是否超出一个页面,是则将当前页面移除
container.removeView(views.get(position));
} }

完整java代码:

 package com.example.myviewpager;

 import java.util.ArrayList;
import java.util.List; import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType; public class MainActivity extends Activity { private ImageView imageView;
//自定义Pager适配器继承PagerAdapter
private MyPagerAdapter adapter;
// ViewPager控件
private ViewPager viewPager;
//存放View类数据的集合
private List<View> views; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); viewPager = (ViewPager) findViewById(R.id.viewPager); initView(); } private void initView() {
//加载ViewPager中显示的页面
//实例化集合
views = new ArrayList<View>();
int image[] = new int[]{R.drawable.a1,R.drawable.a2,R.drawable.a3}; for(int i=;i<=;i++)
{
//实例化中ViewPager中要显示的图片控件
imageView = new ImageView(getApplicationContext());
//设置图片格式
imageView.setScaleType(ScaleType.CENTER_CROP);
imageView.setImageResource(image[i-]);
views.add(imageView); }
//实例化适配器
adapter = new MyPagerAdapter();
//设置适配器 viewPager.setAdapter(adapter);
//设置移除UI的间隔大小,默认为1
// viewPager.setOffscreenPageLimit(3); } //声明PagerAdapter子类,用于管理ViewPager中显示的View控件
class MyPagerAdapter extends PagerAdapter
{ @Override
public int getCount() {
// TODO Auto-generated method stub
return views.size();
} //判断当前显示的UI对象是否和数据对象一致
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
// TODO Auto-generated method stub
return arg0 == arg1;
} @Override
public Object instantiateItem(ViewGroup container, int position) {
//获得指定位置的View,并增加到ViewPager中,同时作为当前页面的数据返回
container.addView(views.get(position));
return views.get(position); } @Override
public void destroyItem(ViewGroup container, int position, Object object) {
//当前位置和ViewPager中正显示的页面的位置的间隔是否超出一个页面,是则将当前页面移除
container.removeView(views.get(position));
} } @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} }

MainActivity.java

效果图;

安卓开发_深入学习ViewPager控件

相关知识:

安卓开发_慕课网_ViewPager切换动画(3.0版本以上有效果)

五、进步一学习,实现底部ViewPager+导航标签的效果

效果为:

底部有导航部分,点击对应的导航按钮(圆点)ViewPager跳转到对应的View界面,

获得ViewPager界面,底部导航圆点对应变化

思路:动态添加导航图标(3个圆点,对应的是ImageView),点击圆点,执行事件响应,ViewPager跳转 viewPager.setCurrentItem(position);//注意下标从0开始

滑动ViewPager,获得当前View界面在ViewPager中的位置,对应显示导航图标(三个圆点)

效果图:

安卓开发_深入学习ViewPager控件

关键部分:

1、动态添加导航图标,并添加响应事件

 //实例化导航图标
ImageView navImage = new ImageView(getApplicationContext());
//给每个导航图标设置一个标签,标签值为i-1 即第一个页面的标签为0 第二个页面的标签为1 第三个页面的标签为2
navImage.setTag(i-);
//将导航图标的ImageView控件添加到其父容器中 ,即LinearLayout中
linearLayout.addView(navImage,layoutParams);
//设置导航图片的点击事件
navImage.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
// TODO Auto-generated method stub
//得到导航图标的位置,显示对应的页面
int position = (Integer) v.getTag();
viewPager.setCurrentItem(position);//注意下标从0开始
}
});
2、选择指定位置的导航图片为选中图片(参数position是当前ViewPager中的子View的位置),即滑动ViewPager 根据当前界面View的位置设置对应导航图标哪个位置的圆点亮
     public void selectNavImage(int position)
{
ImageView navImage = null;
//遍历导航布局中所有的子控件,判断子控件的位置是否为选择位置,
for(int i=;i<linearLayout.getChildCount();i++)
{
navImage = (ImageView) linearLayout.getChildAt(i);
if(i==position)
navImage.setImageResource(R.drawable.page_now); //亮圆点,
else
navImage.setImageResource(R.drawable.page); //暗圆点
}
}

3、设置ViewPager滑动响应事件

 //设置ViewPager的页面滑动事件
viewPager.setOnPageChangeListener(new OnPageChangeListener() { @Override
public void onPageSelected(int arg0) {
//指定位置的页面被选择
selectNavImage(arg0);//显示当前ViewPager中子View的位置所对应的导航图标
} @Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
//第一个参数,滚动页面开始的位置,
//第二个参数,两个页面之间滚动的偏移量,返回值为0--1开区间
//第三个参数,两个页面之间滚动的像素偏移量 } @Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
/*
* 页面滚动状态发生变化时,有开始滚动,停止滚动,正在设置页面三个功能
* ViewPager.SCROLL_STATE_DRAGGING开始滚动
* ViewPager.SCROLL_STATE_IDEL 停止滚动
* ViewPager.SCROLL_STATE_SETTLING 这在设置页面,即将要停止,并且设置当前页显示的页面
*
*/
}
});

4、布局文件中添加导航部分布局

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
> <android.support.v4.view.ViewPager
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/viewPager"
/> <LinearLayout
android:id="@+id/navLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:gravity="center"
android:background="#4000"
android:orientation="horizontal"
android:layout_gravity="bottom"
android:layout_marginBottom="10dp" ></LinearLayout>
</FrameLayout>

完整java代码:

 package com.example.myviewpager;

 import java.util.ArrayList;
import java.util.List; import android.app.Activity;
import android.net.VpnService;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams; public class MainActivity extends Activity { private ImageView imageView;
//自定义Pager适配器继承PagerAdapter
private MyPagerAdapter adapter;
// ViewPager控件
private ViewPager viewPager;
//存放View类数据的集合
private List<View> views; //Demo2
//线性布局中 子控件使用的布局参数对象,用来设置子空间的大小,边距等属性
private LinearLayout.LayoutParams layoutParams;
//存放导航图标的线性布局
private LinearLayout linearLayout;
private ImageView navImage; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); viewPager = (ViewPager) findViewById(R.id.viewPager);
linearLayout = (LinearLayout) findViewById(R.id.navLayout);
//初始化显示的页面
initView(); //Demo2
//设置ViewPager的页面滑动事件
viewPager.setOnPageChangeListener(new OnPageChangeListener() { @Override
public void onPageSelected(int arg0) {
//指定位置的页面被选择
selectNavImage(arg0);//显示当前ViewPager中子View的位置所对应的导航图标
} @Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
//第一个参数,滚动页面开始的位置,
//第二个参数,两个页面之间滚动的偏移量,返回值为0--1开区间
//第三个参数,两个页面之间滚动的像素偏移量 } @Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
/*
* 页面滚动状态发生变化时,有开始滚动,停止滚动,正在设置页面三个功能
* ViewPager.SCROLL_STATE_DRAGGING开始滚动
* ViewPager.SCROLL_STATE_IDEL 停止滚动
* ViewPager.
*
*/
}
}); } private void initView() {
//加载ViewPager中显示的页面
//实例化集合
views = new ArrayList<View>();
int image[] = new int[]{R.drawable.a1,R.drawable.a2,R.drawable.a3};
navImage = null;
//设置子控件(导航图标ImageView)的属性
layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
layoutParams.leftMargin = ; //默认单位ps
layoutParams.rightMargin = ; for(int i=;i<=;i++)
{
//实例化中ViewPager中要显示的图片控件
imageView = new ImageView(getApplicationContext());
//设置图片格式
imageView.setScaleType(ScaleType.CENTER_CROP);
imageView.setImageResource(image[i-]);
views.add(imageView); //实例化导航图标
navImage = new ImageView(getApplicationContext()); //对应每个页面(即红黄蓝图片),设置一个导航图标
if(i==)//默认导航在第一个页面
navImage.setImageResource(R.drawable.page_now);
else
navImage.setImageResource(R.drawable.page);
//给每个导航图标设置一个标签,标签值为i-1 即第一个页面的标签为0 第二个页面的标签为1 第三个页面的标签为2
navImage.setTag(i-);
//将导航图标的ImageView控件添加到其父容器中 ,即LinearLayout中
linearLayout.addView(navImage,layoutParams);
//设置导航图片的点击事件
navImage.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
// TODO Auto-generated method stub
//得到导航图标的位置,显示对应的页面
int position = (Integer) v.getTag();
viewPager.setCurrentItem(position);//注意下标从0开始
}
}); }
//实例化适配器
adapter = new MyPagerAdapter();
//设置适配器 viewPager.setAdapter(adapter);
//设置移除UI的间隔大小,默认为1
// viewPager.setOffscreenPageLimit(3); } //选择指定位置的导航图片为选中图片(参数position是当前ViewPager中的子View的位置)
public void selectNavImage(int position)
{
ImageView navImage = null;
//遍历导航布局中所有的子控件,判断子控件的位置是否为选择位置,
for(int i=;i<linearLayout.getChildCount();i++)
{
navImage = (ImageView) linearLayout.getChildAt(i);
if(i==position)
navImage.setImageResource(R.drawable.page_now);
else
navImage.setImageResource(R.drawable.page);
}
} //声明PagerAdapter子类,用于管理ViewPager中显示的View控件
class MyPagerAdapter extends PagerAdapter
{ @Override
public int getCount() {
// TODO Auto-generated method stub
return views.size();
} //判断当前显示的UI对象是否和数据对象一致
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
// TODO Auto-generated method stub
return arg0 == arg1;
} @Override
public Object instantiateItem(ViewGroup container, int position) {
//获得指定位置的View,并增加到ViewPager中,同时作为当前页面的数据返回
container.addView(views.get(position));
return views.get(position); } @Override
public void destroyItem(ViewGroup container, int position, Object object) {
//当前位置和ViewPager中正显示的页面的位置的间隔是否超出一个页面,是则将当前页面移除
container.removeView(views.get(position));
} } @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} }

MainActivity.java

六、实现ViewPager+Fragment效果

之前写过,就不再写了,直接给以前的链接吧

安卓开发_慕课网_ViewPager与FragmentPagerAdapter实现Tab实现Tab(App主界面)

七、实现ActionBar+ViewPager+Fragment效果

先看下效果图:

安卓开发_深入学习ViewPager控件

这里使用Fragment作为ViewPager的View 实现与ActionBarTab的联合使用

思路:

1、创建四个fragment作为ViewPager的子View

2、创建四个ActionBarTab作为分栏

3、实现ActionBarTab 的 setCurrentItem(int position)方法控制ViewPager页面的跟随变化

实现selectTab(int position)方法 控制ActionBarTab的跟随变化

注意。全部都要导v4包,因为Fragment和ViewPager共同使用的适配器 为v4包下的,需要实现包统一

注意FragmentStatePagerAdapter 适配器和 FragmentPagerAdapter适配器的区别

adapter = new MyFragmentAdapter(getSupportFragmentManager()); 注意这一句话,一定要使类继承FragmentActivity  否则会报错

代码很简单,注释很清楚

 package com.example.viewpagerfragment;

 import java.util.ArrayList;
import java.util.List; import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.ActionBar.TabListener;
import android.app.Activity;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.Menu; public class MainActivity extends FragmentActivity implements TabListener { private List<Fragment> fragmentData;
private MyFragmentAdapter myadapter;
private ViewPager viewPager;
private ActionBar actionBar; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); viewPager = (ViewPager) findViewById(R.id.viewPager);
//创建Fragment对象
initFragment(); initActionBar(); initEvent(); } private void initEvent() {
// TODO Auto-generated method stub
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int arg0) {
// TODO Auto-generated method stub
//当ViewPager滑动的时候,实现ActionBarTab跟随变化
actionBar.selectTab(actionBar.getTabAt(arg0));
} @Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub } @Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub }
});
} private void initActionBar() {
actionBar = getActionBar();
//设置ActionBar的类型为Tab
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
//添加ActionBarTab
actionBar.addTab(actionBar.newTab().setText("热点").setTabListener(this));
actionBar.addTab(actionBar.newTab().setText("国内").setTabListener(this));
actionBar.addTab(actionBar.newTab().setText("国际").setTabListener(this));
actionBar.addTab(actionBar.newTab().setText("娱乐").setTabListener(this)); } private void initFragment() {
//实例化存放fragment的集合
fragmentData = new ArrayList<Fragment>();
fragmentData.add(MyFragment.newMyFagment("热点"));
fragmentData.add(MyFragment.newMyFagment("国内"));
fragmentData.add(MyFragment.newMyFagment("国际"));
fragmentData.add(MyFragment.newMyFagment("娱乐")); //实例化适配器
myadapter = new MyFragmentAdapter(getSupportFragmentManager());
viewPager.setAdapter(myadapter);
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} @Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub } @Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
//当选择ActionBarTab的时候执行viewPager跳转相应的页面
viewPager.setCurrentItem(tab.getPosition());
} @Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub }
//自定义适配器继承FragmentPagerAdapter
class MyFragmentAdapter extends FragmentPagerAdapter{ public MyFragmentAdapter(FragmentManager fm) {
super(fm);
// TODO Auto-generated constructor stub
} @Override
public Fragment getItem(int arg0) {
// TODO Auto-generated method stub
return fragmentData.get(arg0);
} @Override
public int getCount() {
// TODO Auto-generated method stub
return fragmentData.size();
} }
}

MainActivity.java

 package com.example.viewpagerfragment;

 import java.util.ArrayList;
import java.util.List; import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.widget.ArrayAdapter; public class MyFragment extends ListFragment{ private ArrayAdapter<String> adapter;
public static MyFragment newMyFagment(String title)
{
MyFragment mf = new MyFragment();
Bundle bundle = new Bundle();
bundle.putString("title", title);
mf.setArguments(bundle);
return mf;
} @Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
String title = getArguments().getString("title");
adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1);
for(int i=;i<;i++)
{
adapter.add(title+" "+i);
}
} @Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
setListAdapter(adapter);
} }

MyFragment.java

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
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:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" > <android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/viewPager"
> </android.support.v4.view.ViewPager>
</RelativeLayout>

activity_main.xml

上一篇:Kali学习笔记32:Maltego、Exiftool


下一篇:java中POJO类和DTO类都要实现序列化