实例讲解Android中ViewPager组件的一些进阶使用技巧
我们经常看到使用了viewpager的app,在每页上面都会有一个滑块来标志当前处于哪一页。在pagerview包里有android.support.v4.view.pagertitlestrip和android.support.v4.view.pagertabstrip两个组件,可以在布局文件中,作为viewpager的子标签,并设定相对与viewpager的位置(比如顶部)。但这两个组件都很丑,并且标题会随着页面一起滑动,所以一般都不用。
其实实现一个滑块标志当前页面也很简单,大概需要两步:
第一步 在布局文件viewpager的上方放置一个imageview组件,组件可以是图片或是shape资源。注意需要把imageview的scaletype属性设为matrix,就是说该组件的位置和大小由一个变换矩阵来控制;
第二步 在activity中为viewpager组件添加onpagechangelistener监听器。在onpagechangelistener里设定matrix,用于控制指示滑块imageview的位置。该监听器需要实现三个方法:
onpagescrollstatechanged:用于监听滑动状态的改变
onpagescrolled:用于监听滑动的动作
onpageseleted:用于监听页面的切换,即某个页面被选中了作为当前页面。
一般实现onpageselected方法就可以,其他两个方法可以空着。另外为了使页面切换时滑块也是平滑地滑动,可以给滑块的imageview指定一个translateanimation动画,指定动画用setanimation,tranlateanimation也很简单,有个构造函数是translateanimation(int beginx,int endx,int beginy,int endy),将运动矢量的起始位置和终止位置传给它就好了。
下面我们来看五个具体的例子:
一 实现viewpager(数据源为list<view>)
1.先在main.xml文件中添加一个viewpager:
<linearlayout 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/pager" android:layout_width="wrap_content" android:layout_height="wrap_content"> </android.support.v4.view.viewpager> </linearlayout>
2.创建三个view:
<?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" android:orientation="vertical" > <textview android:id="@+id/txt1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:textsize="25dp" android:text="第一页" > </textview> </linearlayout>
<?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" android:orientation="vertical" > <textview android:id="@+id/txt2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="第二页" > </textview> </linearlayout>
<?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" android:orientation="vertical" > <textview android:id="@+id/txt3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="第三页" > </textview> </linearlayout>
3.创建一个viewpager适配器类:
package com.yayun.viewpagerdemo; import java.util.arraylist; import java.util.list; import android.support.v4.view.pageradapter; import android.view.view; import android.view.viewgroup; public class viewpageradapter extends pageradapter { private list<view> lviews=new arraylist<view>(); public viewpageradapter(list<view> lviews){ this.lviews=lviews; } @override public int getcount() { return lviews.size(); } @override public boolean isviewfromobject(view arg0, object arg1) { return arg0==arg1; } @override public object instantiateitem(viewgroup container, int position) { container.addview(lviews.get(position)); return lviews.get(position); } @override public void destroyitem(viewgroup container, int position, object object) { container.removeview(lviews.get(position)); } }
4.mainactivity.java:
package com.yayun.viewpagerdemo; import java.util.arraylist; import java.util.list; import android.support.v7.app.actionbaractivity; import android.support.v7.app.actionbar; import android.support.v4.app.fragment; import android.support.v4.view.pageradapter; import android.support.v4.view.viewpager; import android.os.bundle; import android.view.layoutinflater; import android.view.menu; import android.view.menuitem; import android.view.view; import android.view.viewgroup; import android.view.window; import android.os.build; public class mainactivity extends actionbaractivity { private viewpager viewpager; private list<view> listviews=null; viewpageradapter pageradapter; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); requestwindowfeature(window.feature_no_title); setcontentview(r.layout.activity_main); viewpager=(viewpager) findviewbyid(r.id.pager); listviews=new arraylist<view>(); /** * 为adapter创建数据源 */ view view1=view.inflate(this, r.layout.view1, null); view view2=view.inflate(this, r.layout.view2, null); view view3=view.inflate(this, r.layout.view3, null); listviews.add(view1); listviews.add(view2); listviews.add(view3); pageradapter=new viewpageradapter(listviews) ; viewpager.setadapter(pageradapter); } }
5.运行实例:
可以实现翻页效果。
二 添加标题
1.我们需要更改main.xml文件:
<linearlayout 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/pager" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" > <android.support.v4.view.pagertabstrip android:id="@+id/strip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="top" > </android.support.v4.view.pagertabstrip> </android.support.v4.view.viewpager> </linearlayout>
2.需要更改适配器文件:
package com.yayun.viewpagerdemo; import java.util.arraylist; import java.util.list; import android.support.v4.view.pageradapter; import android.view.view; import android.view.viewgroup; public class viewpageradapter extends pageradapter { private list<view> lviews=new arraylist<view>(); private list<string> titlelist=new arraylist<string>(); public viewpageradapter(list<view> lviews,list<string> titlelist){ this.lviews=lviews; this.titlelist=titlelist; } @override public int getcount() { return lviews.size(); } @override public boolean isviewfromobject(view arg0, object arg1) { return arg0==arg1; } @override public object instantiateitem(viewgroup container, int position) { container.addview(lviews.get(position)); return lviews.get(position); } @override public void destroyitem(viewgroup container, int position, object object) { container.removeview(lviews.get(position)); } /** * 标题 */ @override public charsequence getpagetitle(int position) { // todo auto-generated method stub return titlelist.get(position); } }
3.需要更改mainactivity.java文件:
package com.yayun.viewpagerdemo; import java.util.arraylist; import java.util.list; import android.support.v7.app.actionbaractivity; import android.support.v7.app.actionbar; import android.support.v4.app.fragment; import android.support.v4.view.pageradapter; import android.support.v4.view.pagertabstrip; import android.support.v4.view.viewpager; import android.os.bundle; import android.view.layoutinflater; import android.view.menu; import android.view.menuitem; import android.view.view; import android.view.viewgroup; import android.view.window; import android.os.build; public class mainactivity extends actionbaractivity { private viewpager viewpager; private list<view> listviews=null; viewpageradapter pageradapter; pagertabstrip pagertabstrip; private list<string> titlelist; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); requestwindowfeature(window.feature_no_title); setcontentview(r.layout.activity_main); viewpager=(viewpager) findviewbyid(r.id.pager); pagertabstrip=(pagertabstrip) findviewbyid(r.id.strip); listviews=new arraylist<view>(); titlelist=new arraylist<string>(); titlelist.add("第一页"); titlelist.add("第二页"); titlelist.add("第三页"); /** * 为adapter创建数据源 */ view view1=view.inflate(this, r.layout.view1, null); view view2=view.inflate(this, r.layout.view2, null); view view3=view.inflate(this, r.layout.view3, null); listviews.add(view1); listviews.add(view2); listviews.add(view3); pageradapter=new viewpageradapter(listviews,titlelist) ; viewpager.setadapter(pageradapter); } }
4.运行实例如下:
三 实现viewpager(数据源为list<fragment>)
1.首先我们要创建三个fragment:
package com.yayun.viewpagerdemo; import android.os.bundle; import android.support.v4.app.fragment; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; public class fragment1 extends fragment { @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { return inflater.inflate(r.layout.view1, container, false); } } package com.yayun.viewpagerdemo; import android.os.bundle; import android.support.v4.app.fragment; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; public class fragment2 extends fragment { @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { return inflater.inflate(r.layout.view2, container, false); } } package com.yayun.viewpagerdemo; import android.os.bundle; import android.support.v4.app.fragment; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; public class fragment3 extends fragment { @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { return inflater.inflate(r.layout.view3, container, false); } }
2.设置adapter:
package com.yayun.viewpagerdemo; import java.util.list; import android.support.v4.app.fragment; import android.support.v4.app.fragmentmanager; import android.support.v4.app.fragmentpageradapter; public class myfragmentpageradapter extends fragmentpageradapter { list<fragment> fragmentslist; list<string> titlelist; public myfragmentpageradapter(fragmentmanager fm,list<fragment> fragmentslist,list<string> titlelist) { super(fm); this.fragmentslist=fragmentslist; this.titlelist=titlelist; } @override public fragment getitem(int arg0) { // todo auto-generated method stub return fragmentslist.get(arg0); } @override public int getcount() { // todo auto-generated method stub return fragmentslist.size(); } @override /** * 添加标题 */ public charsequence getpagetitle(int position) { // todo auto-generated method stub return titlelist.get(position); } }
3.mainactivity.java:
package com.yayun.viewpagerdemo; import java.util.arraylist; import java.util.list; import android.graphics.color; import android.os.bundle; import android.support.v4.app.fragment; import android.support.v4.view.pagertabstrip; import android.support.v4.view.viewpager; import android.support.v4.view.viewpager.pagetransformer; import android.support.v7.app.actionbaractivity; import android.view.view; import android.view.window; public class mainactivity extends actionbaractivity { private viewpager viewpager; private list<view> listviews=null; viewpageradapter pageradapter; pagertabstrip pagertabstrip; private list<string> titlelist; private list<fragment> fragmentslist; myfragmentpageradapter myfragmentpageradapter; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); requestwindowfeature(window.feature_no_title); setcontentview(r.layout.activity_main); viewpager=(viewpager) findviewbyid(r.id.pager); pagertabstrip=(pagertabstrip) findviewbyid(r.id.strip); /** * 设置pagertabstrip属性 */ pagertabstrip.setbackgroundcolor(color.green); pagertabstrip.setdrawfullunderline(false); pagertabstrip.settextcolor(color.white); listviews=new arraylist<view>(); titlelist=new arraylist<string>(); fragmentslist=new arraylist<fragment>(); fragmentslist.add(new fragment1()); fragmentslist.add(new fragment2()); fragmentslist.add(new fragment3()); titlelist.add("第一页"); titlelist.add("第二页"); titlelist.add("第三页"); /** * 为adapter创建数据源 */ view view1=view.inflate(this, r.layout.view1, null); view view2=view.inflate(this, r.layout.view2, null); view view3=view.inflate(this, r.layout.view3, null); listviews.add(view1); listviews.add(view2); listviews.add(view3); pageradapter=new viewpageradapter(listviews,titlelist) ; myfragmentpageradapter=new myfragmentpageradapter(getsupportfragmentmanager(), fragmentslist, titlelist); //viewpager.setadapter(pageradapter); viewpager.setadapter(myfragmentpageradapter); } }
4.运行实例:
这种方法不会销毁不在当前页面的页面,不能实现页卡的创建和销毁。
四 实现viewpager(数据源为list<fragment>实现fargmentstatepageradapter)常用
改变adapter:
package com.yayun.viewpagerdemo; import java.util.list; import android.support.v4.app.fragment; import android.support.v4.app.fragmentmanager; import android.support.v4.app.fragmentpageradapter; import android.support.v4.app.fragmentstatepageradapter; import android.view.view; public class myfragmentpageradapter2 extends fragmentstatepageradapter { list<fragment> fragmentslist; list<string> titlelist; public myfragmentpageradapter2(fragmentmanager fm,list<fragment> fragmentslist,list<string> titlelist) { super(fm); this.fragmentslist=fragmentslist; this.titlelist=titlelist; } @override public fragment getitem(int arg0) { // todo auto-generated method stub return fragmentslist.get(arg0); } @override public int getcount() { // todo auto-generated method stub return fragmentslist.size(); } @override /** * 添加标题 */ public charsequence getpagetitle(int position) { // todo auto-generated method stub return titlelist.get(position); } @override public object instantiateitem(view container, int position) { // todo auto-generated method stub return super.instantiateitem(container, position); } @override public void destroyitem(view container, int position, object object) { // todo auto-generated method stub super.destroyitem(container, position, object); } }
将mainactivity.java中的adapter换一下即可,它可以实现页卡的创建和销毁。
五 onpagerchangelistener 监听使用
只需要修改mainactivity.java:
package com.yayun.viewpagerdemo; import java.util.arraylist; import java.util.list; import android.graphics.color; import android.os.bundle; import android.support.v4.app.fragment; import android.support.v4.view.pagertabstrip; import android.support.v4.view.viewpager; import android.support.v4.view.viewpager.onpagechangelistener; import android.support.v4.view.viewpager.pagetransformer; import android.support.v7.app.actionbaractivity; import android.view.view; import android.view.window; import android.widget.toast; public class mainactivity extends actionbaractivity implements onpagechangelistener { private viewpager viewpager; private list<view> listviews=null; viewpageradapter pageradapter; pagertabstrip pagertabstrip; private list<string> titlelist; private list<fragment> fragmentslist; myfragmentpageradapter myfragmentpageradapter; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); requestwindowfeature(window.feature_no_title); setcontentview(r.layout.activity_main); viewpager=(viewpager) findviewbyid(r.id.pager); pagertabstrip=(pagertabstrip) findviewbyid(r.id.strip); /** * 设置pagertabstrip属性 */ pagertabstrip.setbackgroundcolor(color.green); pagertabstrip.setdrawfullunderline(false); pagertabstrip.settextcolor(color.white); listviews=new arraylist<view>(); titlelist=new arraylist<string>(); fragmentslist=new arraylist<fragment>(); fragmentslist.add(new fragment1()); fragmentslist.add(new fragment2()); fragmentslist.add(new fragment3()); titlelist.add("第一页"); titlelist.add("第二页"); titlelist.add("第三页"); /** * 为adapter创建数据源 */ view view1=view.inflate(this, r.layout.view1, null); view view2=view.inflate(this, r.layout.view2, null); view view3=view.inflate(this, r.layout.view3, null); listviews.add(view1); listviews.add(view2); listviews.add(view3); pageradapter=new viewpageradapter(listviews,titlelist) ; myfragmentpageradapter=new myfragmentpageradapter(getsupportfragmentmanager(), fragmentslist, titlelist); //viewpager.setadapter(pageradapter); viewpager.setadapter(myfragmentpageradapter); viewpager.setonpagechangelistener(this);//加载监听器 } @override 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) { toast.maketext(this, "当前页面为"+(arg0+1), toast.length_short).show(); } }
运行实例即可以显示当前页面标签。