首先让大家有个全局的认识,直接上个项目,看看仅仅通过这几行代码,竟然就能完成如此强悍的功能。下篇再结合API仔细讲讲为什么要这么写。


实现了三个view间的相互滑动

  第一个VIEW向第二个VIEW滑动, 第二个VIEW向第三个VIEW滑动

一、新建项目,引入ViewPager控件

ViewPager。它是google SDk中自带的一个附加包的一个类,可以用来实现屏幕间的切换。



1.在主布局文件里加入

<?xml version="1.0" encoding="utf-8"?>
<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="example.com.myapplication.MainActivity">

<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"></android.support.v4.view.ViewPager>
</RelativeLayout>


其中 <android.support.v4.view.ViewPager /> 是ViewPager对应的组件,要将其放到想要滑动的位置



2、新建三个layout,用于滑动切换的视图


从效果图中也可以看到,我们的三个视图都非常简单,里面没有任何的控件,大家当然可以往里添加各种控件,但这里是个DEMO,只详解原理即可,所以我这里仅仅用背景来区别不用layout布局。




布局代码分别如下:

layout1.xml

<?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"
android:background="#ffffff">

</LinearLayout>

layout2.xml

<?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"
android:background="#ffff00">

</LinearLayout>

layout3.xml

<?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"
android:background="#ff00ff">

</LinearLayout>


二、代码实战


先上整体代码,然后逐步讲解。


public class MainActivity extends AppCompatActivity {

private ViewPager viewpage;
private LayoutInflater inflater;
private View view1;
private View view2;
private View view3;
private List<View> listViews;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewpage = (ViewPager) findViewById(R.id.viewpager);
inflater = getLayoutInflater();
view1 = inflater.inflate(R.layout.layout1, null);
view2 = inflater.inflate(R.layout.layout2, null);
view3 = inflater.inflate(R.layout.layout3, null);

//将分页view装进数组中
listViews = new ArrayList<>();
listViews.add(view1);
listViews.add(view2);
listViews.add(view3);

PagerAdapter pagerAdapter = new PagerAdapter() {
@Override
public int getCount() {
return listViews==null ?0:listViews.size();
}

@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}

@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(listViews.get(position));
return listViews.get(position);
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(listViews.get(position));
}
};
viewpage.setAdapter(pagerAdapter);

}
}


PageAdapter——PageView的适配器


适配器这个东东想必大家都不莫生,在ListView中也有适配器,listView通过重写GetView()函数来获取当前要加载的Item。而PageAdapter不太相同,毕竟PageAdapter是单个VIew的合集。




PageAdapter 必须重写的四个函数:




boolean isViewFromObject(View arg0, Object arg1)


int getCount() 


void destroyItem(ViewGroup container, int position,Object object)


Object instantiateItem(ViewGroup container, int position)


先看看各个函数,我们上面都做了什么吧:



getCount():返回要滑动的VIew的个数

destroyItem():从当前container中删除指定位置(position)的View;

instantiateItem():做了两件事,第一:将当前视图添加到container中,第二:返回当前View

isViewFromObject():函数用来判断instantiateItem(ViewGroup, int)函数所返回来的Key与一个页面视图是否是代表的同一个视图(即它俩是否是对应的,对应的表示同一个View)