Android仿京东、天猫app的商品详情页的布局架构, 以及功能实现
前言
电商内app,重点在于详情页商品展示,用户不仅要看到图,可以看到各种描述,以及相关规格参数。
有需要做电商类app的童鞋可以看看, 首先先看看效果实现
- 本项目使用的第三方框架:
- 加载网络图片使用的 Fresco
- 头部的商品图轮播 ConvenientBanner
- 导航栏切换 PagerSlidingTabStrip
先看看效果实现
由于代码量过多, 就不一一讲解只介绍几个核心的自定义控件)
不想看的童鞋可以下载apk或者在github上下载源码使用
- github地址
- apk下载
- 最外层的布局文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!-- 顶部标题 --> <LinearLayout android:id="@+id/ll_title_root" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#ec0f38" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="44dp" android:orientation="horizontal"> <LinearLayout android:id="@+id/ll_back" android:layout_width="wrap_content" android:layout_height="match_parent" android:paddingLeft="15dp"> <ImageView android:id="@+id/iv_back" android:layout_width="22dp" android:layout_height="22dp" android:layout_gravity="center_vertical" android:src="@mipmap/address_come_back" /> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center"> <!-- 商品、详情、评价切换的控件 --> <com.gxz.PagerSlidingTabStrip android:id="@+id/psts_tabs" android:layout_width="wrap_content" android:layout_height="32dp" android:layout_gravity="center" android:textColor="#ffffff" android:textSize="15sp" app:pstsDividerColor="@android:color/transparent" app:pstsDividerPaddingTopBottom="0dp" app:pstsIndicatorColor="#ffffff"
- ItemWebView是SlideDetailsLayout的子View (SlideDetailsLayout代码太多, 放到了最后)
- 功能为显示商品简介的webview
- 防止往上滑动时会直接滑动到第一个View
- 实现滑动到WebView顶部时, 让父控件重新获得触摸事件
/** * 商品详情页底部的webview */ public class ItemWebView extends WebView { public float oldY; private int t; private float oldX; public ItemWebView(Context context) { super(context); } public ItemWebView(Context context, AttributeSet attrs) { super(context, attrs); } public ItemWebView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_MOVE: float Y = ev.getY(); float Ys = Y - oldY; float X = ev.getX(); //滑动到顶部让父控件重新获得触摸事件 if (Ys > 0 && t == 0) { getParent().getParent().requestDisallowInterceptTouchEvent(false); } break; case MotionEvent.ACTION_DOWN: getParent().getParent().requestDisallowInterceptTouchEvent(true); oldY = ev.getY(); oldX = ev.getX(); break; case MotionEvent.ACTION_UP: getParent().getParent().requestDisallowInterceptTouchEvent(true); break; default: break; } return super.onTouchEvent(ev); } @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { this.t = t; super.onScrollChanged(l, t, oldl, oldt); } }
- ItemListView 也是SlideDetailsLayout的子View
- 和ItemWebView功能大致一样
/** * 商品详情页底部的ListView */ public class ItemListView extends ListView implements AbsListView.OnScrollListener { private float oldX, oldY; private int currentPosition; public ItemListView(Context context) { super(context); setOnScrollListener(this); } public ItemListView(Context context, AttributeSet attrs) { super(context, attrs); setOnScrollListener(this); } public ItemListView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setOnScrollListener(this); } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_MOVE: float Y = ev.getY(); float Ys = Y - oldY; float X = ev.getX(); int [] location = new int [2]; getLocationInWindow(location); //滑动到顶部让父控件重新获得触摸事件 if (Ys > 0 && currentPosition == 0) { getParent().getParent().requestDisallowInterceptTouchEvent(false); } break; case MotionEvent.ACTION_DOWN: getParent().getParent().requestDisallowInterceptTouchEvent(true); oldY = ev.getY(); oldX = ev.getX(); break; case MotionEvent.ACTION_UP: getParent().getParent().requestDisallowInterceptTouchEvent(true); break; default: break; } return super.onTouchEvent(ev); } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { currentPosition = getFirstVisiblePosition(); } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } }
- NoScrollViewPager为最外层的父布局
- 当滑动到图文详情模块时, 能禁止掉ViewPager的滑动事件
/** * 提供禁止滑动功能的自定义ViewPager */ public class NoScrollViewPager extends ViewPager { private boolean noScroll = false; public NoScrollViewPager(Context context, AttributeSet attrs) { super(context, attrs); } public NoScrollViewPager(Context context) { super(context); } public void setNoScroll(boolean noScroll) { this.noScroll = noScroll; } @Override public void scrollTo(int x, int y) { super.scrollTo(x, y); } @Override public boolean onTouchEvent(MotionEvent arg0) { if (noScroll) return false; else return super.onTouchEvent(arg0); } @Override public boolean onInterceptTouchEvent(MotionEvent arg0) { if (noScroll) return false; else return super.onInterceptTouchEvent(arg0); } @Override public void setCurrentItem(int item, boolean smoothScroll) { super.setCurrentItem(item, smoothScroll); } @Override public void setCurrentItem(int item) { super.setCurrentItem(item); } }
商品模块最外层的布局是一个自定义的ViewGroup名为SlideDetailsLayout
SlideDetailsLayout内容有两个View, mFrontView(第一个View)和mBehindView(第二个View)
有两种状态, 状态设置为close就显示第一个商品数据View, open状态就显示第二个图文详情View
相关推荐
rookieding 2020-07-26
kangtingting0 2020-06-28
xfcyhades 2020-11-20
huha 2020-10-16
sgafdsg 2020-11-04
Michael 2020-11-03
fengyeezju 2020-10-14
ziyexiaoxiao 2020-10-14
业余架构师 2020-10-09
OuNuo0 2020-09-29
moses 2020-09-22
Angelia 2020-09-11
qinxu 2020-09-10
刘炳昭 2020-09-10
Nostalgiachild 2020-09-07
Nostalgiachild 2020-08-17
leavesC 2020-08-14
一青年 2020-08-13
AndroidAiStudy 2020-08-07