博客
关于我
Android仿京东、天猫商品详情页
阅读量:796 次
发布时间:2023-03-28

本文共 5690 字,大约阅读时间需要 18 分钟。

实现京东、天猫详情页面效果的优化版

项目结构分析

要实现类似京东、天猫详情页面的滑动切换效果,我们需要以下功能:

  • 顶部可以滑动切换Tab(如商品详情与参数页)
  • 下方可以滑动展示图文详情
  • 支持评价显示
  • 从技术实现来看,我们需要:

    • 顶部Tab可以使用ViewPager+Fragment或系统的TabLayout控件实现
    • 下方滑动效果可以采用网上流行的DragLayout控件或自行实现
    • 详情页面和参数页面可以通过Fragment实现
    • 评价页面同样可以通过Fragment实现

    项目结构大致如下:

    com.xzh.gooddetail.view├── FragmentDetail.java  ├── FragmentParameter.java  ├── FragmentEvaluate.java  └── SlideDetailsLayout.java

    核心代码解读

    本节主要讲解自行实现的具有阻尼效果的滑动Layout,以及相关的Fragment逻辑。

    滑动Layout的实现

    1. 拦截事件处理

    @Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {    ensureTarget();    if (null == mTarget) {        return false;    }    if (!isEnabled()) {        return false;    }    final int action = MotionEventCompat.getActionMasked(ev);    boolean shouldIntercept = false;    switch (action) {        case MotionEvent.ACTION_DOWN:            mInitMotionX = ev.getX();            mInitMotionY = ev.getY();            shouldIntercept = false;            break;        case MotionEvent.ACTION_MOVE:            final float x = ev.getX();            final float y = ev.getY();            final float xDiff = x - mInitMotionX;            final float yDiff = y - mInitMotionY;            if (canChildScrollVertically((int) yDiff)) {                shouldIntercept = false;            } else {                final float xDiffabs = Math.abs(xDiff);                final float yDiffabs = Math.abs(yDiff);                if (yDiffabs > mTouchSlop && yDiffabs >= xDiffabs &&                    !(mStatus == Status.CLOSE && yDiff > 0 ||                        mStatus == Status.OPEN && yDiff < 0)) {                    shouldIntercept = true;                }            }            break;        case MotionEvent.ACTION_UP:        case MotionEvent.ACTION_CANCEL:            shouldIntercept = false;            break;    }    return shouldIntercept;}

    2. onTouchEvent处理

    @Overridepublic boolean onTouchEvent(MotionEvent ev) {    ensureTarget();    if (null == mTarget) {        return false;    }    if (!isEnabled()) {        return false;    }    boolean wantTouch = true;    final int action = MotionEventCompat.getActionMasked(ev);    switch (action) {        case MotionEvent.ACTION_DOWN:            if (mTarget instanceof View) {                wantTouch = true;            }            break;        case MotionEvent.ACTION_MOVE:            final float y = ev.getY();            final float yDiff = y - mInitMotionY;            if (canChildScrollVertically((int) yDiff)) {                wantTouch = false;            } else {                processTouchEvent(yDiff);                wantTouch = true;            }            break;        case MotionEvent.ACTION_UP:        case MotionEvent.ACTION_CANCEL:            finishTouchEvent();            wantTouch = false;            break;    }    return wantTouch;}

    3. 滑动效果处理

    private void processTouchEvent(final float offset) {    if (Math.abs(offset) < mTouchSlop) {        return;    }    final float oldOffset = mSlideOffset;    if (mStatus == Status.CLOSE) {        if (offset >= 0) {            mSlideOffset = 0;        } else {            mSlideOffset = offset;        }        if (mSlideOffset == oldOffset) {            return;        }    } else if (mStatus == Status.OPEN) {        final float pHeight = -getMeasuredHeight();        if (offset <= 0) {            mSlideOffset = pHeight;        } else {            final float newOffset = pHeight + offset;            mSlideOffset = newOffset;        }        if (mSlideOffset == oldOffset) {            return;        }    }    requestLayout();}

    4. 动画处理

    private void animatorSwitch(final float start, final float end, final boolean changed, final long duration) {    ValueAnimator animator = ValueAnimator.ofFloat(start, end);    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {        @Override        public void onAnimationUpdate(ValueAnimator animation) {            mSlideOffset = (float) animation.getAnimatedValue();            requestLayout();        }    });    animator.addListener(new AnimatorListenerAdapter() {        @Override        public void onAnimationEnd(Animator animation) {            super.onAnimationEnd(animation);            if (changed) {                if (mStatus == Status.OPEN) {                    checkAndFirstOpenPanel();                }                if (null != mOnSlideDetailsListener) {                    mOnSlideDetailsListener.onStatusChanged(mStatus);                }            }        }    });    animator.setDuration(duration);    animator.start();}

    Fragment实现

    1. FragmentDetail

    public class FragmentDetail extends Fragment {    public static FragmentDetail newInstance() {        return new FragmentDetail();    }    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        return inflater.inflate(R.layout.fragment_detail, container, false);    }}

    2. FragmentParameter

    public class FragmentParameter extends Fragment {    public static FragmentParameter newInstance() {        return new FragmentParameter();    }    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        return inflater.inflate(R.layout.fragment_parameter, container, false);    }}

    3. FragmentEvaluate

    public class FragmentEvaluate extends Fragment {    public static FragmentEvaluate newInstance() {        return new FragmentEvaluate();    }    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        return inflater.inflate(R.layout.fragment_evaluate, container, false);    }}

    总结

    以上是实现京东、天猫详情页面效果的优化版代码讲解。通过自定义的SlideDetailsLayout和多个Fragment,我们实现了复杂的滑动切换效果。代码中还包含了一些优化方案,建议在实际使用中根据项目需求进行调整和优化。

    转载地址:http://mihfk.baihongyu.com/

    你可能感兴趣的文章
    Objective-C实现奇偶检验码(附完整源码)
    查看>>
    Objective-C实现奇偶转置排序算法(附完整源码)
    查看>>
    Objective-C实现奇异值分解SVD(附完整源码)
    查看>>
    Objective-C实现子集总和算法(附完整源码)
    查看>>
    Objective-C实现字符串autocomplete using trie(使用 trie 自动完成)算法(附完整源码)
    查看>>
    Objective-C实现字符串boyer moore search博耶摩尔搜索算法(附完整源码)
    查看>>
    Objective-C实现字符串IP地址转DWORD地址(附完整源码)
    查看>>
    Objective-C实现字符串jaro winkler算法(附完整源码)
    查看>>
    Objective-C实现字符串manacher马拉车算法(附完整源码)
    查看>>
    Objective-C实现字符串wildcard pattern matching通配符模式匹配算法(附完整源码)
    查看>>
    Objective-C实现字符串word patterns单词模式算法(附完整源码)
    查看>>
    Objective-C实现字符串Z 函数或 Z 算法(附完整源码)
    查看>>
    Objective-C实现字符串加解密(附完整源码)
    查看>>
    Objective-C实现字符串复制功能(附完整源码)
    查看>>
    Objective-C实现字符串是否回文Palindrome算法 (附完整源码)
    查看>>
    Objective-C实现字符串查找子串(附完整源码)
    查看>>
    Objective-C实现完整的ComplexNumber复数类(附完整源码)
    查看>>
    Objective-C实现实现rabin karp算法(附完整源码)
    查看>>
    Objective-C实现对图像进行色调处理算法(附完整源码)
    查看>>
    Objective-C实现对称矩阵压缩存储(附完整源码)
    查看>>