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

前言

电商内app,重点在于详情页商品展示,用户不仅要看到图,可以看到各种描述,以及相关规格参数。

有需要做电商类app的童鞋可以看看, 首先先看看效果实现

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

加载网络图片使用的 Fresco

头部的商品图轮播 ConvenientBanner

导航栏切换 PagerSlidingTabStrip

先看看效果实现

223a976fe17ca02e34785554acea2597.gif

由于代码量过多, 就不一一讲解只介绍几个核心的自定义控件)

不想看的童鞋可以下载apk或者在github上下载源码使用

github地址

apk下载

最外层的布局文件

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">

android:id="@+id/ll_title_root"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:background="#ec0f38"

android:orientation="vertical">

android:layout_width="match_parent"

android:layout_height="44dp"

android:orientation="horizontal">

android:id="@+id/ll_back"

android:layout_width="wrap_content"

android:layout_height="match_parent"

android:paddingLeft="15dp">

android:id="@+id/iv_back"

android:layout_width="22dp"

android:layout_height="22dp"

android:layout_gravity="center_vertical"

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

android:layout_width="0dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:gravity="center">

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

*/

publicclass ItemWebView extends WebView {

publicfloatoldY;

private intt;

private floatoldX;

publicItemWebView(Context context) {

super(context);

}

publicItemWebView(Context context, AttributeSet attrs) {

super(context, attrs);

}

publicItemWebView(Context context, AttributeSet attrs,intdefStyleAttr) {

super(context, attrs, defStyleAttr);

}

@Override

publicboolean onTouchEvent(MotionEvent ev) {

switch (ev.getAction()) {

caseMotionEvent.ACTION_MOVE:

floatY = ev.getY();

floatYs = Y - oldY;

floatX = ev.getX();

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

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

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

}

break;

caseMotionEvent.ACTION_DOWN:

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

oldY = ev.getY();

oldX = ev.getX();

break;

caseMotionEvent.ACTION_UP:

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

break;

default:

break;

}

returnsuper.onTouchEvent(ev);

}

@Override

protected void onScrollChanged(intl,intt,intoldl,intoldt) {

this.t = t;

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

}

}

ItemListView 也是SlideDetailsLayout的子View

和ItemWebView功能大致一样

/**

* 商品详情页底部的ListView

*/

publicclass ItemListView extends ListView implements AbsListView.OnScrollListener {

private floatoldX, oldY;

private intcurrentPosition;

publicItemListView(Context context) {

super(context);

setOnScrollListener(this);

}

publicItemListView(Context context, AttributeSet attrs) {

super(context, attrs);

setOnScrollListener(this);

}

publicItemListView(Context context, AttributeSet attrs,intdefStyleAttr) {

super(context, attrs, defStyleAttr);

setOnScrollListener(this);

}

@Override

publicboolean onTouchEvent(MotionEvent ev) {

switch (ev.getAction()) {

caseMotionEvent.ACTION_MOVE:

floatY = ev.getY();

floatYs = Y - oldY;

floatX = ev.getX();

int[] location = newint[2];

getLocationInWindow(location);

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

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

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

}

break;

caseMotionEvent.ACTION_DOWN:

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

oldY = ev.getY();

oldX = ev.getX();

break;

caseMotionEvent.ACTION_UP:

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

break;

default:

break;

}

returnsuper.onTouchEvent(ev);

}

@Override

publicvoid onScrollStateChanged(AbsListViewview,intscrollState) {

currentPosition = getFirstVisiblePosition();

}

@Override

publicvoid onScroll(AbsListViewview,intfirstVisibleItem,intvisibleItemCount,inttotalItemCount) {

}

}

NoScrollViewPager为最外层的父布局

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

/**

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

*/

publicclass NoScrollViewPager extends ViewPager {

private boolean noScroll = false;

publicNoScrollViewPager(Context context, AttributeSet attrs) {

super(context, attrs);

}

publicNoScrollViewPager(Context context) {

super(context);

}

publicvoid setNoScroll(boolean noScroll) {

this.noScroll = noScroll;

}

@Override

publicvoid scrollTo(intx,inty) {

super.scrollTo(x, y);

}

@Override

publicboolean onTouchEvent(MotionEvent arg0) {

if (noScroll)

returnfalse;

else

returnsuper.onTouchEvent(arg0);

}

@Override

publicboolean onInterceptTouchEvent(MotionEvent arg0) {

if (noScroll)

returnfalse;

else

returnsuper.onInterceptTouchEvent(arg0);

}

@Override

publicvoid setCurrentItem(intitem, boolean smoothScroll) {

super.setCurrentItem(item, smoothScroll);

}

@Override

publicvoid setCurrentItem(intitem) {

super.setCurrentItem(item);

}

}

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

SlideDetailsLayout内容有两个View, mFrontView(***个View)和mBehindView(第二个View)

有两种状态, 状态设置为close就显示***个商品数据View, open状态就显示第二个图文详情View

@SuppressWarnings("unused")

publicclass SlideDetailsLayout extends ViewGroup {

/**

* Callback forpanelOPEN-CLOSEstatus changed.

*/

publicinterface OnSlideDetailsListener {

/**

* Called afterstatus changed.

*

* @param status {@link Status}

*/

void onStatucChanged(Status status);

}

publicenum Status {

/** Panel isclosed */

CLOSE,

/** Panel isopened */

OPEN;

publicstaticStatus valueOf(intstats) {

if (0 == stats) {

returnCLOSE;

} elseif (1 == stats) {

returnOPEN;

} else{

returnCLOSE;

}

}

}

private staticfinalfloatDEFAULT_PERCENT = 0.2f;

private staticfinalintDEFAULT_DURATION = 300;

private ViewmFrontView;

private ViewmBehindView;

private floatmTouchSlop;

private floatmInitMotionY;

private floatmInitMotionX;

private ViewmTarget;

private floatmSlideOffset;

private Status mStatus = Status.CLOSE;

private boolean isFirstShowBehindView = true;

private floatmPercent = DEFAULT_PERCENT;

private long mDuration = DEFAULT_DURATION;

private intmDefaultPanel = 0;

private OnSlideDetailsListener mOnSlideDetailsListener;

publicSlideDetailsLayout(Context context) {

this(context, null);

}

publicSlideDetailsLayout(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

publicSlideDetailsLayout(Context context, AttributeSet attrs,intdefStyleAttr) {

super(context, attrs, defStyleAttr);

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SlideDetailsLayout, defStyleAttr, 0);

mPercent = a.getFloat(R.styleable.SlideDetailsLayout_percent, DEFAULT_PERCENT);

mDuration = a.getInt(R.styleable.SlideDetailsLayout_duration, DEFAULT_DURATION);

mDefaultPanel = a.getInt(R.styleable.SlideDetailsLayout_default_panel, 0);

这个商品详情页的架构也是本人在已上线的项目中使用

【编辑推荐】

【责任编辑:枯木 TEL:(010)68476606】

点赞 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值