Android控件-ViewPager(仿微信引导界面)
什么是ViewPager?
ViewPager是安卓3.0之后提供的新特性,继承自ViewGroup,专门用以实现左右滑动切换View的效果。
如果想向下兼容就必须要android-support-v4.jar这个包的支持,这是一个来自google提供的一个附加包。
通俗点来讲,就是现在市面上大多数app,安装完第一次打开软件会出现的一个左右滑动的引导界面。
先来看下效果图:
这是一个仿微信的引导界面,图是我抠来的
实现功能:
能够左右滑动页面,下面对应的小圆圈点顺带着走,也可以对小圆点进行点击跳转(有些人可能会采用把小圆点写死,直接画在界面上的背景图,其实这个是个很不好的习惯,太不灵活,一旦改动起来,很不好维护)
其实要实现这种效果并不难,ViewPager这个控件和其他常见控件的实现方式大致相同(比如:ListView)
步骤:声明实例化控件->设置数据源->配置适配器->绑定适配器->(添加监听)
声明控件:
由于该类存在于Google的兼容包里面,所以在引用时记得在BuilldPath中加入“android-support-v4.jar”
<android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="fill_parent" android:layout_height="fill_parent" />
数据源:
这里的是数据源是一个存放着View对象的集合:
实现方式有2种:
1、通过XML配置文件,把对应的页面设置好,然后把xml配置文件转换成view对象并载入这个集合里
2、通过代码动态生成,把生成的View对象载入到集合里。
适配器:
我们需要去继承PagerAdapter类,并覆写相对应的方法(在下面代码部分会详细说)
下面提供必须实现的,最基本的几个方法:
@Override public int getCount() {//返回页面数量 return 0; } @Override public boolean isViewFromObject(View arg0, Object arg1) {//判断是否是view对象 return false; } @Override public Object instantiateItem(View container, int position) {//实例化一个页面 return super.instantiateItem(container, position); } @Override public void destroyItem(View container, int position, Object object) {//销毁一个页面 super.destroyItem(container, position, object); }
当然还可以设置更多样式,比如给ViewPager的每个页面都加入标题等,这里就不再多说,大家自己翻看API吧。
直接上代码吧,本段代码是采用XML布局文件静态生成view对象的,其中有一段注释是提供代码动态生成view的方法,至于用哪个,看个人喜好了。
MainActivity.java(主程序类)
package com.example.wx_viewpagertest; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.Toast; public class MainActivity extends Activity implements OnPageChangeListener,OnClickListener{ private ViewPager viewPager; private List<View> viewList; //private int images[]={R.drawable.v1,R.drawable.v2,R.drawable.v3,R.drawable.v4};//导航图片资源 private View view1, view2, view3, view4; private ImageView points[];//存放小圆圈数组 private int currentIndex=0;//当前页面,默认首页 private Button startButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initViewPager();//初始化ViewPager对象 initPoint();//初始化导航小圆点 } private void initPoint() { LinearLayout linearLayout=(LinearLayout) findViewById(R.id.ll); points=new ImageView[4]; for(int i=0;i<points.length;i++){ points[i]=(ImageView) linearLayout.getChildAt(i);//遍历LinearLayout下的所有ImageView子节点 points[i].setEnabled(true);//设置当前状态为允许(可点,灰色) //设置点击监听 points[i].setOnClickListener(this); //额外设置一个标识符,以便点击小圆点时跳转对应页面 points[i].setTag(i);//标识符与圆点顺序一致 } currentIndex=0; points[currentIndex].setEnabled(false);//设置首页为当前页(小点着色,蓝色) } private void initViewPager() { viewPager=(ViewPager) findViewById(R.id.viewpager);//取得ViewPager实例 viewList=new ArrayList<View>();//实例化list集合 /* 用代码的动态添加View //添加对应的view进入集合(数据源) for(int i=0;i<images.length;i++){ ImageView imageView=new ImageView(MainActivity.this); imageView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT)); imageView.setScaleType(ScaleType.FIT_XY);//设置缩放样式 imageView.setImageResource(images[i]); viewList.add(imageView); } */ //用xml静态添加view view1=View.inflate(MainActivity.this, R.layout.view1, null); view2=View.inflate(MainActivity.this, R.layout.view2, null); view3=View.inflate(MainActivity.this, R.layout.view3, null); view4=View.inflate(MainActivity.this, R.layout.view4, null); viewList.add(view1); viewList.add(view2); viewList.add(view3); viewList.add(view4); //设置适配器 ImageAdapter adapter=new ImageAdapter(viewList); //绑定适配器 viewPager.setAdapter(adapter); //设置页卡切换监听 viewPager.setOnPageChangeListener(this); } @Override public void onPageScrollStateChanged(int arg0) { } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageSelected(int position ) {//当前页卡被选择时,position为当前页数 if(position==3){//由于进入微信这个按钮在第4个页面(view)才会出现,如果一开始就加载这个按钮监听,就导致空指针异常 startButton=(Button) findViewById(R.id.startbutton); startButton.setOnClickListener(new OnClickListener() {//匿名内部类,区分小圆圈的点击事件 @Override public void onClick(View v) { Toast.makeText(MainActivity.this, "欢迎进入微信世界", Toast.LENGTH_SHORT).show(); } }); } points[position].setEnabled(false);//不可点 points[currentIndex].setEnabled(true);//恢复之前页面状态 currentIndex=position; } @Override public void onClick(View v) { //利用刚设置的标识符跳转页面 //Log.i("tuzi",v.getTag()+""); viewPager.setCurrentItem((int) v.getTag()); } }
ImageAdapter.java(适配器类)
package com.example.wx_viewpagertest; import java.util.List; import android.support.v4.view.PagerAdapter; import android.view.View; import android.view.ViewGroup; public class ImageAdapter extends PagerAdapter { private List<View> list; public ImageAdapter(List<View> list) {// 利用构造器接收list集合参数 this.list = list; } @Override public int getCount() {// 返回页卡数量 if (list.size() != 0) { return list.size(); } return 0; } @Override public boolean isViewFromObject(View arg0, Object arg1) {//判断是否为view对象 return arg0==arg1;//官方demo给出的建议写法 } @Override public Object instantiateItem(ViewGroup container, int position) {//实例化一个页卡,view对象存放在ViewGroup里 container.addView(list.get(position)); return list.get(position); } @Override public void destroyItem(ViewGroup container, int position, Object object) {//销毁一个页卡 container.removeView(list.get(position)); } }
XML布局文件这里就不都贴出来了,就是简简单单的设置图片,文字按钮等
只贴其中比较特别的view:
主界面xml(activity_main.xml):
<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" tools:context="com.example.wx_viewpagertest.MainActivity" > <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="fill_parent" android:layout_height="fill_parent" /> <LinearLayout android:id="@+id/ll" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="20dp" android:orientation="horizontal" > <ImageView android:id="@+id/iv1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:clickable="true" android:padding="25dp" android:src="@drawable/point_selector" /> <ImageView android:id="@+id/iv2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:clickable="true" android:padding="25dp" android:src="@drawable/point_selector" /> <ImageView android:id="@+id/iv3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:clickable="true" android:padding="25dp" android:src="@drawable/point_selector" /> <ImageView android:id="@+id/iv4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:clickable="true" android:padding="25dp" android:src="@drawable/point_selector" /> </LinearLayout> </RelativeLayout>
最后一个页面带进入按钮的xml(view4.xml):
<?xml version="1.0" encoding="UTF-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/v4" android:orientation="vertical" > <TextView android:id="@+id/starttext" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:gravity="center" android:layout_marginTop="80dp" android:text="微信,是一种生活方式" android:textColor="@android:color/white" android:textSize="20dp" /> <Button android:id="@+id/startbutton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="80dp" android:background="@drawable/startbutton_selector" android:text="@string/start" android:textColor="@android:color/white" android:textSize="18dp" /> </RelativeLayout>
这里还有个选择器,自定义小圆圈和Button按钮样式:
小圆圈:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:state_enabled="true" android:drawable="@drawable/v_point_nor" ></item> <item android:state_enabled="false" android:drawable="@drawable/v_point_pre" ></item> </selector>
自定义按钮:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="true" android:state_pressed="true" android:drawable="@drawable/v_btn_pressed" /> <item android:state_enabled="true" android:drawable="@drawable/v_btn_nor" /> </selector>