ViewPager是一个滑动容器,可以在其中添加View左右滑动实现滑动效果
首先,Viewpager需要在xml布局中添加一个
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.viewpagertest.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>
这里在主布局文件中定义了一个ViewPager
然后再MainActivity中,我们创建这样一个实例,并且通过findviewbyid方式找到它;
ViewPager需要一个PagerAdapter适配器:
viewPager= (ViewPager) findViewById(R.id.viewpager);
viewPager.setAdapter(new PagerAdapter() {
@Override
public int getCount() {
return mlist.size();
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(mlist.get(position));
return mlist.get(position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(mlist.get(position));
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
});
里面总共需要重写四个方法
第一个方法getcount 要返回的就是ViewPager中View的数目,在这里我们定义几个imageview,并且添加到一个list<imageview>集合中,返回的是list.size();
第二个方法
public Object instantiateItem(ViewGroup container, int position) {
container.addView(mlist.get(position));
return mlist.get(position);
}
这个是要求传回具体的View,参数中的position就是当前view的索引,我们从list中取出来就可以
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(mlist.get(position));
}
第三个方法是当手指滑动导致这个View切出去的时候,从容器中移除掉响应的View,避免占用内存过多
第四个方法
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
我也不知道为啥,反正就是这么写呗,随后有时间在研究。
Viewpager总体来说还是很简单的,就是定义一些View然后放入集合中,给Viewpager配置一个适配器,从集合中取出相对应的View
同时ViewPager还可以设置切屏时的动画,在GooGle的官方教程中,给出了两个实例,这里就不贴出来了。
ZoomOutPageTransformer
Depth Page Transformer
两个动画效果,如此设置
viewPager.setPageTransformer(true,new DepthPageTransformer());
同时,给出官方的例子:
public class DepthPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.75f;
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 0) { // [-1,0]//position实在[-1,1]这个区间中,当[-1,0)中,A页已经开始部分退出屏幕,在这里可以做出A页推出的动画
// Use the default slide transition when moving to the left page
view.setAlpha(1);
view.setTranslationX(0);
view.setScaleX(1);
view.setScaleY(1);
} else if (position <= 1) { // (0,1]//官方给出的例子是在(0,1]中,此时B页正在进入屏幕,在这里可以给出B页进入的动画效果,如果进出动画都一样,
//不用判断是否小于0了
view.setAlpha(1 - position);
// Counteract the default slide transition
view.setTranslationX(pageWidth * -position);
// Scale the page down (between MIN_SCALE and 1)
float scaleFactor = MIN_SCALE
+ (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
如果要自定义动画,必须设置一个类继承Pagetransformer 并且重新写里面的方法,在transformpage方法中重写动画
显然,我们单纯的在ViewPager中添加View有时候是不够的,我们想添加更多界面,这时候就可以添加Fragment到Viewpager中
例如,我们先在XML文件中编写两个界面,同时写两个类来继承Fragment,在这两个类中的oncreat方法中通过以下代码返回界面
public class FindFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.firstframgent2,container,false);
}
}
与此同时,在MainActivity中,让MainActivity继承FragmentAcitivity,然后实例化出刚才的Fragment对象,然后用list来装载两个fragment
此处的适配器为FragmentPageAdapter
adapter=new FragmentPagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {
return mfragment.get(position);
}
@Override
public int getCount() {
return mfragment.size();
}
};
需要的参数为FragmentMnager对象,通过getSupportFragmentManager方法来获得。再将适配器适配给ViewPager,此时Viewpager就可以通过滑动来得到多个Fragment界面了
但是,仅仅这些还是不够的,我们很多时候还需要知道滑动的时候是什么状态,这时我们就需要监听滑动事件
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//Log.i("kk","position:"+position+","+"positionOffset:"+positionOffset+",positionOffsetPixels:"+positionOffsetPixels);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) tabline.getLayoutParams();
layoutParams.leftMargin= (int) (currentitem*mScreen3_1+(positionOffset+position-currentitem)*mScreen3_1);
Log.i("kk","layoutParams.leftMargin:"+layoutParams.leftMargin+",position:"+position+",currentitem:"+currentitem);
tabline.setLayoutParams(layoutParams);
}
@Override
public void onPageSelected(int position) {
ChangeTextColor(position);
ChangebadeView();
currentitem=position;
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
0-->1 position:一直是0,直到滑动到第二页才会变成1 positionOffset:0~1不断渐进 positionOffsetPixels:0~屏幕宽度
1-->0 position:一直是0 positionOffset:1~~0 不断渐进 positionOffsetPixels:屏幕宽度~~0
1-->2 position:一直是1,直到滑动到第三页才会变成2 positionOffset:0~1不断渐进 positionOffsetPixels:0~屏幕宽度
2-->1 position:一直是1 positionOffset:1~~0 不断渐进 positionOffsetPixels:屏幕宽度~~0
这样我们在模拟微信的滑动指示器的过程中可以通过设置
layoutParams.leftMargin= (int) (currentitem*mScreen3_1+(positionOffset+position-currentitem)*mScreen3_1)
当前页数*屏幕的1/3+(positionoffset+position-currentitem)*屏幕的1/3
我们首先要在onPageSelected方法中得到滑动前的页面,然后通过以上的规律,position-currentitm得到的数字,当向右滑的时候是正数,这个时候margin会继续加大,而当左滑的时候就成了负数,margin就会变小。这样我们就实现了指示器的功能。
另外,还学到了其他东西,比如获得屏幕的相关信息 ,通过以下方法
private void inittabline() {
tabline= (ImageView) findViewById(R.id.tabline);
Display display=getWindow().getWindowManager().getDefaultDisplay();
DisplayMetrics outmetrics=new DisplayMetrics();
display.getMetrics(outmetrics);
mScreen3_1=outmetrics.widthPixels/3;
ViewGroup.LayoutParams layoutParams = tabline.getLayoutParams();
layoutParams.width=mScreen3_1;
tabline.setLayoutParams(layoutParams);
}
最后,总结一下,就是先写好Fragment界面,并且写Fragment的子类,装载到list中,主活动要继承FragmentActivity,这是个要初始化适配器FragmentPageAdaPter
并在适配器中的方法中返回fragment,然后为viewpager设置适配器。或者为viewpager添加动画,要写一个类继承Pagetransform,重写里面的方法,然后设置动画。
或者设置监听事件。