ViewPager+Tab特效实现微信主界面-笔记

1、为什么Fragment传递参数时使用setArgument而不是属性赋值?

程序在切换到后台时可能会因为内存不足而销毁fragment,再次切换到前台时会重建fragment(横竖屏切换也会导致fragment销毁重建),使用setArgument传递参数的话系统重建fragment时会自动恢复数据,而属性赋值则不会。

2、为什么调试程序时要将log封装成单独的类?代码如下:

public class L {
    private static final String TAG = "ZXK";
    private static boolean sDebug= BuildConfig.DEBUG;
    public static void d(String msg,Object... args){
        if(!sDebug){
            return;
        }
        Log.d(TAG, String.format(msg,args));
    }
}

程序发布时挨个删除log很麻烦,通过封装类可以统一管理log,不必在代码中逐个修改log。

3、FragmentStatePagerAdapter和FragmentPagerAdapter的区别是什么?

在ViewPager滑动时,超出setOffscreenPageLimit设置范围的Fragment销毁和重建的时候FragmentStatePagerAdapter执行onDestroyView、onDestroy、onCreate、onCreateView四个方法、即完全销毁释放内存,而FragmentPagerAdapter只执行onDestroyView、onCreateView两个方法。所以FragmentStatePagerAdapter适合数量极大的情况,如图片浏览,而FragmentPagerAdapter适合用在主界面,数量少不需要常驻内存的情况。

4、ViewPager中使用的Fragment为什么不能在Activity的onCreate中直接实例化?

横竖屏切换等情况导致Activity重建时会重新实例化Fragment,而ViewPager会通过getSupportFragmentManager管理原来Fragment的销毁和重建。这会使程序中操作的Fragment和ViewPager中的不是一个,导致程序出现异常!

5、Activity向ViewPager中的Fragment传递参数的一种解决方案:

通过SparseArray<>构造Fragment列表,Key是int类型,value是Object类型。SparseArray比map效率高很多。

6、Fragment向Activity传值:

在Fragment中使用getActivity可以实现传值,但是Fragment与Activity耦合,实际开发中没有这么用的,应该使用接口传递数据。

7、滑动ViewPager页面时如何实现图标颜色渐变(或其他过渡效果)?

ViewPager的OnPageChangeListener接口中的方法

public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)

它的第二个参数positionOffset的含义是当前position位置页面距离ViewPager中心的偏移值,范围是0-1,当值为1时position的值发生改变(即页面切换,此时position变为新页面,positionoffset变为0)positionOffset会随着滑动而变化。图标渐变效果可以在这个方法中设置。

8、如何自定义视图?

自定义控件一般有两种方式,手动绘制控件和多个系统控件组合。这里介绍系统控件组合的方式:

1)自定义一个类继承自ViewGroup或其子类,如FrameLayout。

2)实现两个参数的构造函数,并在构造函数中加载布局文件。

3)通过方法或xml为属性赋值。

9、如何为ViewPager设置滑动特效?

通过void setPageTransformer(boolean reverseDrawingOrder,PageTransformer transformer)设置动画效果。

参数1:滑入页面和滑出页面如果重叠,哪一个在上面。

参数2:实现动画效果的接口,为了方便复用,通常创建自定义类实现这个接口。

ViewPager.PageTransformer接口理解。PageTransformer有一个方法

void transformPage(@NonNull View page, float position)

参数1:需要实现动画的页面,具体是哪个页面由position的值决定。

参数2:页面的位置。值为-1~0时参数1为左侧滑入或滑出页面,0~1时参数1为右侧滑入或滑出页面,小于-1和大于1分别参数1为左侧和右侧其他页面。

滑动时两侧缩小75%,半透明效果实现代码:

public class ScaleTransformer implements ViewPager.PageTransformer {
    public static final float MIN_SCALE = 0.75f;
    public static final float MIN_ALPHA = 0.5f;

    @Override
    public void transformPage(@NonNull View page, float position) {
        L.d("transformPage,page=" + page.getTag() + "position=" + position);
        if (position < -1) {
            page.setScaleX(MIN_SCALE);
            page.setScaleY(MIN_SCALE);
            page.setAlpha(MIN_ALPHA);
        } else if (position <= 1) {
            if (position < 0) {
                float scaleA = MIN_SCALE + (1 - MIN_SCALE) * (1 + position);
                page.setScaleX(scaleA);
                page.setScaleY(scaleA);
                float alphaA = MIN_ALPHA + (1 - MIN_ALPHA) * (1 + position);
                page.setAlpha(alphaA);
            } else {
                float scaleB = MIN_SCALE + (1 - MIN_SCALE) * (1 - position);
                page.setScaleX(scaleB);
                page.setScaleY(scaleB);
                float alphaB = MIN_ALPHA + (1 - MIN_ALPHA) * (1 - position);
                page.setAlpha(alphaB);
            }
        } else {
            page.setScaleX(MIN_SCALE);
            page.setScaleY(MIN_SCALE);
            page.setAlpha(MIN_ALPHA);
        }
    }
}

滑动时轮盘效果实现代码:

public class RotateTransformer implements ViewPager.PageTransformer {
    public static final float DEGREE_ROTATE = 15;

    @Override
    public void transformPage(@NonNull View page, float position) {
        L.d("transformPage,page=" + page.getTag() + "position=" + position);
        int width = page.getWidth();
        int height = page.getHeight();
        if (position < -1) {

        } else if (position <= 1) {
            if (position < 0) {
                float x = width - width / 2 * (1 + position);
                page.setPivotX(x);
                page.setPivotY(height);
                page.setRotation(-DEGREE_ROTATE+DEGREE_ROTATE*(1+position));
            } else {
                float x = width / 2 * (1 - position);
                page.setPivotX(x);
                page.setPivotY(height);
                page.setRotation(DEGREE_ROTATE-DEGREE_ROTATE*(1-position));
            }
        } else {

        }
    }
}

10、如何让ViewPager显示两侧部分页面?

1)在布局文件中将ViewPager的父布局的ClipChildren属性设置为false。

2)在布局文件中为ViewPager设置margin属性。

3)在java代码中设置ViewPager的setPageMargin属性,这个不是必须设置。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值