混合开发经验之谈-2TH

第二次bug 处理

在遇到上一次问题——页面不能通过正确的html地址加载显示页面内容。解决之后,又出现了新的问题!什么问题呢?地图这一个页面,太卡了,经常的出现render error cpu顶不住!怎么办?对于使用的AgentWeb,她的浏览器内核使用是ChromiumCrosswalk 使用的不是Android的webview,而是一个有效的Chromium的修订版本基于Blink-Chromium,其中Chromium是Google的Chrome浏览器的开源基础。当然,Crosswalk 在性能上要远高于原生的webview,但是项目会徒然增加 20M+。然,综合考虑,决定换!

Crosswalk 使用介绍

配置

//首先:Manifest 中开启硬件加速
//Project:build.gradle
repositories {  
    maven {  
        url 'https://download.01.org/crosswalk/releases/crosswalk/android/maven2'}  
}  

//Module:build.gradle
dependencies {  
    compile 'org.xwalk:xwalk_core_library:23.53.589.4'  
}  

productFlavors {
        armv7 {
            ndk {
                abiFilters "armeabi-v7a"
            }
        }
        x86 {
            ndk {
                abiFilters "x86"
            }
        }
    }

使用 https://download.01.org/crosswalk/releases/crosswalk/android/maven2 跳入的网页中,选择需要的版本。

这里写图片描述

ok,到内部核心代码的更换到H5端调用的交互方式的更换之后,运行检阅效果。发现,地图的渲染效率明显增加,页面的画面效果更加清晰逼真。运行结果表明,这个 crosswalk 虽然在空间体积上不让人满意外,其他效果还是挺不错的。

第三次bug 处理

但是好景不长,在进行项目测试的时候,又遇到了棘手的问题。4个tab页面的切换有时候不灵了,Jesus(耶稣)!!这就有些匪夷所思了,效果是这样的: 进入主页面时,默认第一个tab被选中,且内容显示第一页面内容;然后点击第2或3或4,只是 tab进行了切换(选中状态变化),而tab对应的页面内容不变,特别需要强调的是tab的点击是有监听,无论页面切换与否都有监听。听上去是不是很扯?怎么解决,这问题过于刁专。
经过后期的项目实践发现,这些问题的病因在于(1)手机,(2)html页面。当然html页面我无法要求,毕竟不是我写的。所以只能提升移动端的性能来弥补。如果有机会你可以尝试一下,极度放慢viewpager的页面切换的时间,就会发现一切无问题。但是,只要极致缩短切换时间(当然都是追求更好的效果)就会发现,好手机没事,差点的手机要么切换不动,要么切换的两个页面内容有部分的重叠覆盖。

先介绍一下基础:基础框架是 TabHost + ViewPager(CusViewPager) + Fragment,所以在操作功能上跟微信是一模一样,既可以点击tab进行切换,也可以通过滑动进行切换。但是考虑到第一页面的地图手势很复杂,于是要禁用手势的滑动切换。然后就重写了一个 ViewPager,禁止了滑动操作功能。又考虑到想要更靠近微信的操作,所有在重写的 ViewPager中也把切换的动画给禁止了。

经过各种尝试之后,发现了一个突破点曙光
发现给页面切换添加切换的动画,整个切换就没有问题了。说来也是很神奇,有切换动画和没有切换动画,对于 TabHost + ViewPager(CusViewPager) + Fragment 而言,不就是拿到监听 Fragment 发生变换吗?但事实是监听有,变换不执行。唯有添加切换的动画,才能执行。
重写ViewPager的切换动画的基类 PageTransformer:

public abstract class ABaseTransformer implements PageTransformer {

    /**
     * Called each {@link #transformPage(View, float)}.
     * 
     * @param page
     *            Apply the transformation to this page
     * @param position
     *            Position of page relative to the current front-and-center position of the pager. 0 is front and
     *            center. 1 is one full page position to the right, and -1 is one page position to the left.
     */
    protected abstract void onTransform(View page, float position);

    /**
     * Apply a property transformation to the given page. For most use cases, this method should not be overridden.
     * Instead use {@link #transformPage(View, float)} to perform typical transformations.
     * 
     * @param page
     *            Apply the transformation to this page
     * @param position
     *            Position of page relative to the current front-and-center position of the pager. 0 is front and
     *            center. 1 is one full page position to the right, and -1 is one page position to the left.
     */
    @Override
    public void transformPage(View page, float position) {
        onPreTransform(page, position);
        onTransform(page, position);
        onPostTransform(page, position);
    }

    /**
     * If the position offset of a fragment is less than negative one or greater than one, returning true will set the
     * fragment alpha to 0f. Otherwise fragment alpha is always defaulted to 1f.
     * 
     * @return
     */
    protected boolean hideOffscreenPages() {
        return true;
    }

    /**
     * Indicates if the default animations of the view pager should be used.
     * 
     * @return
     */
    protected boolean isPagingEnabled() {
        return false;
    }

    /**
     * Called each {@link #transformPage(View, float)} before {{@link #onTransform(View, float)}.
     * <p>
     * The default implementation attempts to reset all view properties. This is useful when toggling transforms that do
     * not modify the same page properties. For instance changing from a transformation that applies rotation to a
     * transformation that fades can inadvertently leave a fragment stuck with a rotation or with some degree of applied
     * alpha.
     * 
     * @param page
     *            Apply the transformation to this page
     * @param position
     *            Position of page relative to the current front-and-center position of the pager. 0 is front and
     *            center. 1 is one full page position to the right, and -1 is one page position to the left.
     */
    protected void onPreTransform(View page, float position) {
        final float width = page.getWidth();

        page.setRotationX(0);
        page.setRotationY(0);
        page.setRotation(0);
        page.setScaleX(1);
        page.setScaleY(1);
        page.setPivotX(0);
        page.setPivotY(0);
        page.setTranslationY(0);
        page.setTranslationX(isPagingEnabled() ? 0f : -width * position);

        if (hideOffscreenPages()) {
            page.setAlpha(position <= -1f || position >= 1f ? 0f : 1f);
            page.setEnabled(false);
        } else {
            page.setEnabled(true);
            page.setAlpha(1f);
        }
    }

    /**
     * Called each {@link #transformPage(View, float)} after {@link #onTransform(View, float)}.
     * 
     * @param page
     *            Apply the transformation to this page
     * @param position
     *            Position of page relative to the current front-and-center position of the pager. 0 is front and
     *            center. 1 is one full page position to the right, and -1 is one page position to the left.
     */
    protected void onPostTransform(View page, float position) {
    }

    /**
     * Same as {@link Math#min(double, double)} without double casting, zero closest to infinity handling, or NaN support.
     * 
     * @param val
     * @param min
     * @return
     */
    protected static final float min(float val, float min) {
        return val < min ? min : val;
    }

}

切换动画的具体实现:

/**
 * Created by YJH on 2017/12/27.
 * 功能:viewpager 的动画切换动画实现类
 * 为什么使用 动画呢?因为没有动画,在小米机子上,使用TabLayout+Fragment 进行点击按钮页面切换时,不能实现效果!(华为手机上没问题)
 * 虽然使用这种方法实现,但是还有一点,就是切换的动画太长,这时候,需要重写 类Scroller 降低动画的切换时间
 */
public class ForeToBackTransformer extends ABaseTransformer {

    @Override
    protected void onTransform(View view, float position) {
        final float height = view.getHeight();
        final float width = view.getWidth();
        final float scale = min(position > 0 ? 1f : Math.abs(1f + position), 0.5f);

        view.setScaleX(scale);
        view.setScaleY(scale);
        view.setPivotX(width * 0.5f);
        view.setPivotY(height * 0.5f);
        view.setTranslationX(position > 0 ? width * position : -width * position * 0.25f);
    }

}

好,我就给你添加切换的动画。满足你的需求!然后运行成功,bug解决。但效果不太满意,因为切换动画那是有动画的执行时间,有的甚至切换动画是各种各样,3D的什么的我不用,我使用的就是普通的变换,但是动画时间导致切换明显的空白延迟效果,怎么办?然后突然就想到能不能减少切换的动画时间,自己去设置?好,有了设想,就去搞。

/**
 * Created by YJH on 2017/12/27.
 * 功能:viewpager 的动画切换动画实现类
 * 为什么使用 动画呢?因为没有动画,在小米机子上,使用TabLayout+Fragment 进行点击按钮页面切换时,不能实现效果!(华为手机上没问题)
 * 虽然使用这种方法实现,但是还有一点,就是切换的动画太长,这时候,需要重写 类Scroller 降低动画的切换时间
 */
public class FixedSpeedScroller extends Scroller {
    private int mDuration = 1;
    public FixedSpeedScroller(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    public FixedSpeedScroller(Context context, Interpolator interpolator) {
        super(context, interpolator);
    }

    @Override
    public void startScroll(int startX, int startY, int dx, int dy, int duration) {
        // Ignore received duration, use fixed one instead
        super.startScroll(startX, startY, dx, dy, mDuration);
    }

    @Override
    public void startScroll(int startX, int startY, int dx, int dy) {
        // Ignore received duration, use fixed one instead
        super.startScroll(startX, startY, dx, dy, mDuration);
    }

    /**
     * 设置切换时间
     */
    public void setmDuration(int time) {
        mDuration = time;
    }

    /**
     * 获取切换时间
     */
    public int getmDuration() {
        return mDuration;
    }
}

找到并重写之后,就要到项目代码中去设置:

这里写图片描述

代码中可以看到 设置动画的代码:viewPager.setPageTransformer(true, new ForeToBackTransformer());

设置动画时间的代码:

try {
            // 通过class文件获取mScroller属性
            //重写 类Scroller 降低动画的切换时间
            Field mField = ViewPager.class.getDeclaredField("mScroller");
            mField.setAccessible(true);
            mScroller = new FixedSpeedScroller(viewPager.getContext(), new AccelerateInterpolator());
            mField.set(viewPager, mScroller);
        } catch (Exception e) {
            e.printStackTrace();
        }
        mScroller.setmDuration(1);

到此,已完成了需求。谢谢我追求完美的不屑努力。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值