继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

【备战春招】第21天 通用UI组件开发与基础框架设计

Link0
关注TA
已关注
手记 22
粉丝 0
获赞 4

课程名称:移动端架构师


课程章节:通用UI组件开发与基础框架设计

课程讲师:CrazyCodeBoy LovelyChubby


课程内容:

需求分析

设计一个底部导航组件:

  • 能够提供通用的API

  • 支持透明度和底部透出

  • 支持Tab中间高度超过,凸起布局效果

  • 支持iconfont

  • 支持Bitmap

疑难点分析

  • 透明度和底部透出,列表可渲染高度问题

  • 中间高度超过,凸起布局

功能模块拆分

  • 外层容器控件

  • 底部单个Tab控件

  • 每个Tab对应的实体

  • 外层容器控件的对外接口

  • 底部单个Tab控件的对外接口

  • Tab切换监听器

http://img1.sycdn.imooc.com/63f8087c0001d7e824731221.jpg



HiTabTop组件封装

需求分析

设计一个底部导航组件:

  • 能够提供通用的API

  • 支持text

  • 支持Bitmap

  • 支持自动滚动

疑难点分析

  • 自动滚动,实现点击的位置能够自动滚动以展示前后2个

功能模块拆分

  • 外层容器控件

  • 顶部单个Tab控件

  • 每个Tab对应的实体

  • 外层容器控件的对外接口

  • 顶部单个Tab控件的对外接口

  • Tab切换监听器

http://img1.sycdn.imooc.com/63f8089b00013b1924531143.jpg



RecyclerView中使用ViewPager问题

问题

在RecyclerView中使用ViewPager时,会出现两个常见的bug:

  • RecyclerView滚动上去,直至ViewPager看不见,再滚动下来,ViewPager下一次切换没有动画

  • 当ViewPage滚动到一半的时候,RecyclerView滚动上去,再滚动下来,ViewPager会卡在一半

问题1:原因

ViewPager里有一个私有变量mFirstLayout,它是表示是不是第一次显示布局,如果是true,则使用无动画的方式显示当前item,如果是false,则使用动画方式显示当前item。

void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int velocity) {
    ...

    if (mFirstLayout) {
        // We don't have any idea how big we are yet and shouldn't have any pages either.
        // Just set things up and let the pending layout handle things.
        mCurItem = item;
        if (dispatchSelected) {
            dispatchOnPageSelected(item);
        }
        requestLayout();
    } else {
        populate(item);
        scrollToItem(item, smoothScroll, velocity, dispatchSelected);

    ...
}

当ViewPager滚动上去后,因为RecyclerView的回收机制,ViewPager会走onDetachFromWindow,当再次滚动下来时,ViewPager会走onAttachedToWindow,而问题就出在onAttachToWindow。

@Override
protected void onAttachedToWindow() {
    super.onAttachedToWindow();
    mFirstLayout = true;
}

原来如此,在onAttachedToWindow中,mFirstLayout被重置为true,所以下一次滚动就没有动画。

问题1:解决方法

重写onAttachedToWindow方法,把mFirstLayout再重置成false,因为mFirstLayout是private变量,我们不能直接访问,所以只能反射了。

@Override
protected void onAttachedToWindow() {
    super.onAttachedToWindow();
    try {
        Field mFirstLayout = ViewPager.class.getDeclaredField("mFirstLayout");
        mFirstLayout.setAccessible(true);
        mFirstLayout.set(this, false);
        getAdapter().notifyDataSetChanged();
        setCurrentItem(getCurrentItem());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

问题2:原因

直接来看ViewPager的onDetachFromWindow方法

@Override
protected void onDetachedFromWindow() {
    removeCallbacks(mEndScrollRunnable);
    // To be on the safe side, abort the scroller
    if ((mScroller != null) && !mScroller.isFinished()) {
        mScroller.abortAnimation();
    }
    super.onDetachedFromWindow();
}

上述代码直接把动画强行停掉了。

问题2:解决方法

想来想去,没什么好办法,只能想办法保护了

@Override
protected void onDetachedFromWindow() {
    if (hasActivityDestroy) {
        super.onDetachedFromWindow();
    }
}

public void setHasDestroy(boolean hasDestroy) {
    hasActivityDestroy= hasDestroy;
}

当activity destroy的时候,给自定义ViewPager一个标志位hasActivityDestroy,只有hasActivityDestroy为true的时候,才调用父类的super.onDetachedFromWindow();



课程收获:

谢谢老师,讲的非常细致,期待后边的继续学习



http://img2.sycdn.imooc.com/63f829d600018f9613800861.jpg

http://img2.sycdn.imooc.com/63fc14d30001d13211460972.jpg


http://img3.sycdn.imooc.com/63fc6a0a0001bd0116050878.jpg




打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP