Android仿京东、天猫app的商品详情页的布局架构, 以及功能实现

来源:互联网 发布:人类登月是真是假 知乎 编辑:程序博客网 时间:2024/06/03 19:08

前言:电商内app,重点在于详情页商品展示,用户不仅要看到图,可以看到各种描述,以及相关规格参数。今天是coexist独家授权本公众号独家发布的《仿京东、天猫app的商品详情页功能实现》,并且已经用于他的上线项目中,coexist的简书:http://www.jianshu.com/u/ab76a93a9384,点击【阅读原文】,可看本文对应链接,下面是正文部分。


首先先看看效果实现:




    • 本项目使用的第三方框架:

      • 加载网络图片使用的 Fresco

      • 头部的商品图轮播 ConvenientBanner

      • 导航栏切换 PagerSlidingTabStrip

最外层的布局文件

  1. <?xml version="1.0" encoding="utf-8"?>

  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

  3.    xmlns:app="http://schemas.android.com/apk/res-auto"

  4.    xmlns:tools="http://schemas.android.com/tools"

  5.    android:layout_width="match_parent"

  6.    android:layout_height="match_parent"

  7.    android:orientation="vertical">

  8.     <!-- 顶部标题 -->

  9.    <LinearLayout

  10.        android:id="@+id/ll_title_root"

  11.        android:layout_width="match_parent"

  12.        android:layout_height="wrap_content"

  13.        android:background="#ec0f38"

  14.        android:orientation="vertical">

  15.        <LinearLayout

  16.            android:layout_width="match_parent"

  17.            android:layout_height="44dp"

  18.            android:orientation="horizontal">

  19.            <LinearLayout

  20.                android:id="@+id/ll_back"

  21.                android:layout_width="wrap_content"

  22.                android:layout_height="match_parent"

  23.                android:paddingLeft="15dp">

  24.                <ImageView

  25.                    android:id="@+id/iv_back"

  26.                    android:layout_width="22dp"

  27.                    android:layout_height="22dp"

  28.                    android:layout_gravity="center_vertical"

  29.                    android:src="@mipmap/address_come_back" />

  30.            </LinearLayout>

  31.            <LinearLayout

  32.                android:layout_width="0dp"

  33.                android:layout_height="match_parent"

  34.                android:layout_weight="1"

  35.                android:gravity="center">

  36.                <!-- 商品、详情、评价切换的控件 -->

  37.                <com.gxz.PagerSlidingTabStrip

  38.                    android:id="@+id/psts_tabs"

  39.                    android:layout_width="wrap_content"

  40.                    android:layout_height="32dp"

  41.                    android:layout_gravity="center"

  42.                    android:textColor="#ffffff"

  43.                    android:textSize="15sp"

  44.                    app:pstsDividerColor="@android:color/transparent"

  45.                    app:pstsDividerPaddingTopBottom="0dp"

  46.                    app:pstsIndicatorColor="#ffffff"

  47.                    app:pstsIndicatorHeight="2dp"

  48.                    app:pstsScaleZoomMax="0.0"

  49.                    app:pstsShouldExpand="false"

  50.                    app:pstsSmoothScrollWhenClickTab="false"

  51.                    app:pstsTabPaddingLeftRight="12dp"

  52.                    app:pstsTextAllCaps="false"

  53.                    app:pstsTextSelectedColor="#ffffff"

  54.                    app:pstsUnderlineHeight="0dp" />

  55.                <TextView

  56.                    android:id="@+id/tv_title"

  57.                    android:layout_width="wrap_content"

  58.                    android:layout_height="wrap_content"

  59.                    android:text="图文详情"

  60.                    android:textColor="#ffffff"

  61.                    android:textSize="15sp"

  62.                    android:visibility="gone" />

  63.            </LinearLayout>

  64.        </LinearLayout>

  65.    </LinearLayout>

  66.     <!-- 功能下面有介绍 -->

  67.    <com.hq.hsmwan.widget.NoScrollViewPager

  68.        android:id="@+id/vp_content"

  69.        android:layout_width="match_parent"

  70.        android:layout_height="0dp"

  71.        android:layout_weight="1" />

  72. </LinearLayout>

ItemWebView是SlideDetailsLayout的子View (SlideDetailsLayout代码太多, 放到了最后)

  • 功能为显示商品简介的webview

  • 防止往上滑动时会直接滑动到第一个View

  • 实现滑动到WebView顶部时, 让父控件重新获得触摸事件

  1. /**

  2. * 商品详情页底部的webview

  3. */

  4. public class ItemWebView extends WebView {

  5.    public float oldY;

  6.    private int t;

  7.    private float oldX;

  8.    public ItemWebView(Context context) {

  9.        super(context);

  10.    }

  11.    public ItemWebView(Context context, AttributeSet attrs) {

  12.        super(context, attrs);

  13.    }

  14.    public ItemWebView(Context context, AttributeSet attrs, int defStyleAttr) {

  15.        super(context, attrs, defStyleAttr);

  16.    }

  17.    @Override

  18.    public boolean onTouchEvent(MotionEvent ev) {

  19.        switch (ev.getAction()) {

  20.            case MotionEvent.ACTION_MOVE:

  21.                float Y = ev.getY();

  22.                float Ys = Y - oldY;

  23.                float X = ev.getX();

  24.                //滑动到顶部让父控件重新获得触摸事件

  25.                if (Ys > 0 && t == 0) {

  26.                    getParent().getParent().requestDisallowInterceptTouchEvent(false);

  27.                }

  28.                break;

  29.            case MotionEvent.ACTION_DOWN:

  30.                getParent().getParent().requestDisallowInterceptTouchEvent(true);

  31.                oldY = ev.getY();

  32.                oldX = ev.getX();

  33.                break;

  34.            case MotionEvent.ACTION_UP:

  35.                getParent().getParent().requestDisallowInterceptTouchEvent(true);

  36.                break;

  37.            default:

  38.                break;

  39.        }

  40.        return super.onTouchEvent(ev);

  41.    }

  42.    @Override

  43.    protected void onScrollChanged(int l, int t, int oldl, int oldt) {

  44.        this.t = t;

  45.        super.onScrollChanged(l, t, oldl, oldt);

  46.    }

  47. }

  48. ItemListView 也是SlideDetailsLayout的子View

  49. ItemWebView功能大致一样

  50. /**

  51. * 商品详情页底部的ListView

  52. */

  53. public class ItemListView extends ListView implements AbsListView.OnScrollListener {

  54.    private float oldX, oldY;

  55.    private int currentPosition;

  56.    public ItemListView(Context context) {

  57.        super(context);

  58.        setOnScrollListener(this);

  59.    }

  60.    public ItemListView(Context context, AttributeSet attrs) {

  61.        super(context, attrs);

  62.        setOnScrollListener(this);

  63.    }

  64.    public ItemListView(Context context, AttributeSet attrs, int defStyleAttr) {

  65.        super(context, attrs, defStyleAttr);

  66.        setOnScrollListener(this);

  67.    }

  68.    @Override

  69.    public boolean onTouchEvent(MotionEvent ev) {

  70.        switch (ev.getAction()) {

  71.            case MotionEvent.ACTION_MOVE:

  72.                float Y = ev.getY();

  73.                float Ys = Y - oldY;

  74.                float X = ev.getX();

  75.                int [] location = new int [2];

  76.                getLocationInWindow(location);

  77.                //滑动到顶部让父控件重新获得触摸事件

  78.                if (Ys > 0 && currentPosition == 0) {

  79.                    getParent().getParent().requestDisallowInterceptTouchEvent(false);

  80.                }

  81.                break;

  82.            case MotionEvent.ACTION_DOWN:

  83.                getParent().getParent().requestDisallowInterceptTouchEvent(true);

  84.                oldY = ev.getY();

  85.                oldX = ev.getX();

  86.                break;

  87.            case MotionEvent.ACTION_UP:

  88.                getParent().getParent().requestDisallowInterceptTouchEvent(true);

  89.                break;

  90.            default:

  91.                break;

  92.        }

  93.        return super.onTouchEvent(ev);

  94.    }

  95.    @Override

  96.    public void onScrollStateChanged(AbsListView view, int scrollState) {

  97.        currentPosition = getFirstVisiblePosition();

  98.    }

  99.    @Override

  100.    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

  101.    }

  102. }

NoScrollViewPager为最外层的父布局

  • 当滑动到图文详情模块时, 能禁止掉ViewPager的滑动事件

  1. /**

  2. * 提供禁止滑动功能的自定义ViewPager

  3. */

  4. public class NoScrollViewPager extends ViewPager {

  5.    private boolean noScroll = false;

  6.    public NoScrollViewPager(Context context, AttributeSet attrs) {

  7.        super(context, attrs);

  8.    }

  9.    public NoScrollViewPager(Context context) {

  10.        super(context);

  11.    }

  12.    public void setNoScroll(boolean noScroll) {

  13.        this.noScroll = noScroll;

  14.    }

  15.    @Override

  16.    public void scrollTo(int x, int y) {

  17.        super.scrollTo(x, y);

  18.    }

  19.    @Override

  20.    public boolean onTouchEvent(MotionEvent arg0) {

  21.        if (noScroll)

  22.            return false;

  23.        else

  24.            return super.onTouchEvent(arg0);

  25.    }

  26.    @Override

  27.    public boolean onInterceptTouchEvent(MotionEvent arg0) {

  28.        if (noScroll)

  29.            return false;

  30.        else

  31.            return super.onInterceptTouchEvent(arg0);

  32.    }

  33.    @Override

  34.    public void setCurrentItem(int item, boolean smoothScroll) {

  35.        super.setCurrentItem(item, smoothScroll);

  36.    }

  37.    @Override

  38.    public void setCurrentItem(int item) {

  39.        super.setCurrentItem(item);

  40.    }

  41. }

商品模块最外层的布局是一个自定义的ViewGroup名为SlideDetailsLayout

SlideDetailsLayout内容有两个View, mFrontView(第一个View)和mBehindView(第二个View)
有两种状态, 状态设置为close就显示第一个商品数据View, open状态就显示第二个图文详情View。

0 0
原创粉丝点击