ViewPager学习心得

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,重写里面的方法,然后设置动画。

或者设置监听事件。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值