Android仿外卖购物车的实现
2016-10-08 12:38
281 查看
又两周没写博客了,不是不想写而是不知道该写点什么,总不能为了写博客而写博客,前两天项目里要加个购物车功能,看了下别人APP的效果觉得不错,虽然我项目里没用上不过毕竟还算是个常用的功能,于是决定写个博客分享下!
- 列表标题悬停
- 左右列表滑动时联动
- 添加商品时的抛物线动画
- 底部弹出购物车清单
- 数据的同步
另外就是实现效果的时候可能会遇到的几个坑。。。
布局很简单直接进入代码
sticky-headers-recyclerview做悬停标题的时候scrollToPosition(int position)方法滚动的位置不准确。
当布局复杂点的时候 如果RecyclerView的宽度自适应或者使用权重百分比之类可能会导致header显示空白。
并且该开源项目作者已经停止维护,所以这次又换回了
需要购物车Demo的很多都是新手,这里简单介绍下StickyListHeadersListView的使用
AS引用 gradle文件dependencies内添加
xml文件中使用StickyListHeadersListView代替ListView
Adapter继承BaseAdapter和接口StickyListHeadersAdapter
StickyListHeadersAdapter接口包括两个方法
代码中使用和ListView一样,下面是几个特有的方法,看方法名也很容易理解用途
- 左侧列表点击选择分类,右侧列表滑动到对应分类
- 右侧列表滑动过程中左侧列表高亮的分类跟随变化
第一个效果简单,左侧列表item添加点击事件,事件中调用右侧列表的setSelection(int positon) 方法。
第二个效果要给右侧列表添加ScrollListener,根据列表中显示的第一条数据设置左侧选中的分类
- 当商品从0到1 旋转左移显示出减号按钮
- 当商品从1到0 减号按钮旋转右移消失
- 添加商品时抛物线动画添加到购物车图标
前两个动画很简单可以分解成三个补间动画 旋转、平移、透明度。
可以用xml完成,也可以代码设置,不过有个小坑要注意一下 旋转动画一定要在平移动画前面,否则就不是滚动平移了,而是乱跳。。。
这里贴一下动画的代码设置方法
抛物线动画和上面的差不多可以分解成两个平移动画,不过两个平移动画的差值器一个线性一个加速而已,因为动画界面跨度比较大所以需要在根部局内写,不能写在列表的item中(这样会显示不全)。
代码中的anim_mask_layout 即为整个布局文件的根布局,这里是一个RelativeLayout
实现过程
1、首先点击加号图标,拿到控件在屏幕上的绝对坐标,回调activity显示动画
2、创建动画的控件并添加到根部局并在动画结束后移除动画view
bottomsheet
集成简单,效果多样这里简单介绍一下使用方法
集成
使用
xml中使用BottomSheetLayout包裹弹出view时候的背景布局,BottomSheetLayout继承自帧布局
代码中使用很简单
SparseArray这个类其实就是 HashMap< Integer,Object >
不过SparseArray既可以根据key查找Value,也可以根据位置查找value,性能比HashMap高,是官方推荐的替代类,
同样SparseIntArray 其实是HashMap< Integer,Integer> 的替代者。
Activity里实现了下面几个方法,用于数据统一管理
列表中显示的商品购买数量统一从activity获取,商品的加减统一调用Activity的方法然后notifiDatasetChanged,由于代码不少具体的还是看源码吧
具体逻辑还是看代码吧,也许有更简单的实现。。。
Demo下载地址,下载到的文件是个AS module,你可以在自己新建的工程中Import Module.
http://download.csdn.net/detail/w804518214/9539602
效果图
知识点分析
效果图来看不复杂内容并没多少,值得介绍一下的知识点也就下面几个吧- 列表标题悬停
- 左右列表滑动时联动
- 添加商品时的抛物线动画
- 底部弹出购物车清单
- 数据的同步
另外就是实现效果的时候可能会遇到的几个坑。。。
布局很简单直接进入代码
列表标题悬停
现在做项目列表什么的基本抛弃了ListView改用RecyclerView,上篇博客中的标题悬停也是使用了一个RecyclerView的开源项目sticky-headers-recyclerview,不过写这个demo的时候遇到了两个坑
sticky-headers-recyclerview做悬停标题的时候scrollToPosition(int position)方法滚动的位置不准确。
当布局复杂点的时候 如果RecyclerView的宽度自适应或者使用权重百分比之类可能会导致header显示空白。
并且该开源项目作者已经停止维护,所以这次又换回了
StickyListHeadersListView。
需要购物车Demo的很多都是新手,这里简单介绍下StickyListHeadersListView的使用
AS引用 gradle文件dependencies内添加
<code class="hljs bash has-numbering"> compile <span class="hljs-string">'se.emilsjolander:stickylistheaders:2.7.0'</span></code><ul class="pre-numbering" style=""><li>1</li></ul><ul class="pre-numbering" style=""><li>1</li></ul>
xml文件中使用StickyListHeadersListView代替ListView
<code class="hljs avrasm has-numbering"> <se<span class="hljs-preprocessor">.emilsjolander</span><span class="hljs-preprocessor">.stickylistheaders</span><span class="hljs-preprocessor">.StickyListHeadersListView</span> android:layout_width=<span class="hljs-string">"match_parent"</span> android:background=<span class="hljs-string">"#fff"</span> android:id=<span class="hljs-string">"@+id/itemListView"</span> android:layout_height=<span class="hljs-string">"match_parent"</span>> </se<span class="hljs-preprocessor">.emilsjolander</span><span class="hljs-preprocessor">.stickylistheaders</span><span class="hljs-preprocessor">.StickyListHeadersListView</span>></code>
Adapter继承BaseAdapter和接口StickyListHeadersAdapter
StickyListHeadersAdapter接口包括两个方法
<code class="hljs cs has-numbering"> View getHeaderView(<span class="hljs-keyword">int</span> position, View convertView, ViewGroup parent); <span class="hljs-keyword">long</span> getHeaderId(<span class="hljs-keyword">int</span> position); </code>
代码中使用和ListView一样,下面是几个特有的方法,看方法名也很容易理解用途
<code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setAreHeadersSticky</span>(<span class="hljs-keyword">boolean</span> areHeadersSticky); <span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">areHeadersSticky</span>(); <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setOnHeaderClickListener</span>(OnHeaderClickListener listener); <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">OnHeaderClickListener</span> {</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onHeaderClick</span>(StickyListHeadersListView l, View header, <span class="hljs-keyword">int</span> itemPosition, <span class="hljs-keyword">long</span> headerId, <span class="hljs-keyword">boolean</span> currentlySticky); } <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setOnStickyHeaderChangedListener</span>(OnStickyHeaderChangedListener listener); <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">OnStickyHeaderChangedListener</span> {</span> <span class="hljs-keyword">void</span> onStickyHeaderChanged(StickyListHeadersListView l, View header, <span class="hljs-keyword">int</span> itemPosition, <span class="hljs-keyword">long</span> headerId); } <span class="hljs-keyword">public</span> View <span class="hljs-title">getListChildAt</span>(<span class="hljs-keyword">int</span> index); <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getListChildCount</span>();</code>
左右列表联动
联动主要有两个效果- 左侧列表点击选择分类,右侧列表滑动到对应分类
- 右侧列表滑动过程中左侧列表高亮的分类跟随变化
第一个效果简单,左侧列表item添加点击事件,事件中调用右侧列表的setSelection(int positon) 方法。
第二个效果要给右侧列表添加ScrollListener,根据列表中显示的第一条数据设置左侧选中的分类
<code class="hljs java has-numbering"> listView.setOnScrollListener(<span class="hljs-keyword">new</span> AbsListView.OnScrollListener() { <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onScrollStateChanged</span>(AbsListView view, <span class="hljs-keyword">int</span> scrollState) { } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onScroll</span>(AbsListView view, <span class="hljs-keyword">int</span> firstVisibleItem, <span class="hljs-keyword">int</span> visibleItemCount, <span class="hljs-keyword">int</span> totalItemCount) { <span class="hljs-comment">//根据firstVisibleItem获取分类ID,根据分类id获取左侧要选中的位置</span> GoodsItem item = dataList.get(firstVisibleItem); <span class="hljs-keyword">if</span>(typeAdapter.selectTypeId != item.typeId) { typeAdapter.selectTypeId = item.typeId; typeAdapter.notifyDataSetChanged(); <span class="hljs-comment">//左侧列表是个RecyclerView 所以使用smoothScrollToPosition(int position) 使当对应position的item可以滚动显示出来</span> rvType.smoothScrollToPosition(<span class="hljs-keyword">int</span> position)(getSelectedGroupPosition(item.typeId)); } } });</code>
添加商品的动画
添加商品一共有三个动画- 当商品从0到1 旋转左移显示出减号按钮
- 当商品从1到0 减号按钮旋转右移消失
- 添加商品时抛物线动画添加到购物车图标
前两个动画很简单可以分解成三个补间动画 旋转、平移、透明度。
可以用xml完成,也可以代码设置,不过有个小坑要注意一下 旋转动画一定要在平移动画前面,否则就不是滚动平移了,而是乱跳。。。
这里贴一下动画的代码设置方法
<code class="hljs avrasm has-numbering"> //显示减号的动画 private Animation getShowAnimation(){ AnimationSet <span class="hljs-keyword">set</span> = new AnimationSet(true)<span class="hljs-comment">;</span> RotateAnimation rotate = new RotateAnimation(<span class="hljs-number">0</span>,<span class="hljs-number">720</span>,RotateAnimation<span class="hljs-preprocessor">.RELATIVE</span>_TO_SELF,<span class="hljs-number">0.5</span>f,RotateAnimation<span class="hljs-preprocessor">.RELATIVE</span>_TO_SELF,<span class="hljs-number">0.5</span>f)<span class="hljs-comment">;</span> <span class="hljs-keyword">set</span><span class="hljs-preprocessor">.addAnimation</span>(rotate)<span class="hljs-comment">;</span> TranslateAnimation translate = new TranslateAnimation( TranslateAnimation<span class="hljs-preprocessor">.RELATIVE</span>_TO_SELF,<span class="hljs-number">2</span>f ,TranslateAnimation<span class="hljs-preprocessor">.RELATIVE</span>_TO_SELF,<span class="hljs-number">0</span> ,TranslateAnimation<span class="hljs-preprocessor">.RELATIVE</span>_TO_SELF,<span class="hljs-number">0</span> ,TranslateAnimation<span class="hljs-preprocessor">.RELATIVE</span>_TO_SELF,<span class="hljs-number">0</span>)<span class="hljs-comment">;</span> <span class="hljs-keyword">set</span><span class="hljs-preprocessor">.addAnimation</span>(translate)<span class="hljs-comment">;</span> AlphaAnimation alpha = new AlphaAnimation(<span class="hljs-number">0</span>,<span class="hljs-number">1</span>)<span class="hljs-comment">;</span> <span class="hljs-keyword">set</span><span class="hljs-preprocessor">.addAnimation</span>(alpha)<span class="hljs-comment">;</span> <span class="hljs-keyword">set</span><span class="hljs-preprocessor">.setDuration</span>(<span class="hljs-number">500</span>)<span class="hljs-comment">;</span> return <span class="hljs-keyword">set</span><span class="hljs-comment">;</span> } //隐藏减号的动画 private Animation getHiddenAnimation(){ AnimationSet <span class="hljs-keyword">set</span> = new AnimationSet(true)<span class="hljs-comment">;</span> RotateAnimation rotate = new RotateAnimation(<span class="hljs-number">0</span>,<span class="hljs-number">720</span>,RotateAnimation<span class="hljs-preprocessor">.RELATIVE</span>_TO_SELF,<span class="hljs-number">0.5</span>f,RotateAnimation<span class="hljs-preprocessor">.RELATIVE</span>_TO_SELF,<span class="hljs-number">0.5</span>f)<span class="hljs-comment">;</span> <span class="hljs-keyword">set</span><span class="hljs-preprocessor">.addAnimation</span>(rotate)<span class="hljs-comment">;</span> TranslateAnimation translate = new TranslateAnimation( TranslateAnimation<span class="hljs-preprocessor">.RELATIVE</span>_TO_SELF,<span class="hljs-number">0</span> ,TranslateAnimation<span class="hljs-preprocessor">.RELATIVE</span>_TO_SELF,<span class="hljs-number">2</span>f ,TranslateAnimation<span class="hljs-preprocessor">.RELATIVE</span>_TO_SELF,<span class="hljs-number">0</span> ,TranslateAnimation<span class="hljs-preprocessor">.RELATIVE</span>_TO_SELF,<span class="hljs-number">0</span>)<span class="hljs-comment">;</span> <span class="hljs-keyword">set</span><span class="hljs-preprocessor">.addAnimation</span>(translate)<span class="hljs-comment">;</span> AlphaAnimation alpha = new AlphaAnimation(<span class="hljs-number">1</span>,<span class="hljs-number">0</span>)<span class="hljs-comment">;</span> <span class="hljs-keyword">set</span><span class="hljs-preprocessor">.addAnimation</span>(alpha)<span class="hljs-comment">;</span> <span class="hljs-keyword">set</span><span class="hljs-preprocessor">.setDuration</span>(<span class="hljs-number">500</span>)<span class="hljs-comment">;</span> return <span class="hljs-keyword">set</span><span class="hljs-comment">;</span> } //执行动画 只需给对应控件setAnimation然后调用setVisibility方法即可 { .... tvMinus<span class="hljs-preprocessor">.setAnimation</span>(getHiddenAnimation())<span class="hljs-comment">;</span> tvMinus<span class="hljs-preprocessor">.setVisibility</span>(View<span class="hljs-preprocessor">.GONE</span>)<span class="hljs-comment">;</span> }</code>
抛物线动画和上面的差不多可以分解成两个平移动画,不过两个平移动画的差值器一个线性一个加速而已,因为动画界面跨度比较大所以需要在根部局内写,不能写在列表的item中(这样会显示不全)。
代码中的anim_mask_layout 即为整个布局文件的根布局,这里是一个RelativeLayout
实现过程
1、首先点击加号图标,拿到控件在屏幕上的绝对坐标,回调activity显示动画
<code class="hljs cs has-numbering"> <span class="hljs-keyword">int</span>[] loc = <span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[<span class="hljs-number">2</span>]; v.getLocationInWindow(loc); activity.playAnimation(loc);</code>
2、创建动画的控件并添加到根部局并在动画结束后移除动画view
<code class="hljs cs has-numbering"> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">playAnimation</span>(<span class="hljs-keyword">int</span>[] start_location){ ImageView img = <span class="hljs-keyword">new</span> ImageView(<span class="hljs-keyword">this</span>); img.setImageResource(R.drawable.button_add); setAnim(img,start_location); } <span class="hljs-comment">//创建动画 平移动画直接传递偏移量 </span> <span class="hljs-keyword">private</span> Animation <span class="hljs-title">createAnim</span>(<span class="hljs-keyword">int</span> startX,<span class="hljs-keyword">int</span> startY){ <span class="hljs-keyword">int</span>[] des = <span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[<span class="hljs-number">2</span>]; imgCart.getLocationInWindow(des); AnimationSet <span class="hljs-keyword">set</span> = <span class="hljs-keyword">new</span> AnimationSet(<span class="hljs-keyword">false</span>); Animation translationX = <span class="hljs-keyword">new</span> TranslateAnimation(<span class="hljs-number">0</span>, des[<span class="hljs-number">0</span>]-startX, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>); <span class="hljs-comment">//线性插值器 默认就是线性</span> translationX.setInterpolator(<span class="hljs-keyword">new</span> LinearInterpolator()); Animation translationY = <span class="hljs-keyword">new</span> TranslateAnimation(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, des[<span class="hljs-number">1</span>]-startY); <span class="hljs-comment">//设置加速插值器</span> translationY.setInterpolator(<span class="hljs-keyword">new</span> AccelerateInterpolator()); Animation alpha = <span class="hljs-keyword">new</span> AlphaAnimation(<span class="hljs-number">1</span>,<span class="hljs-number">0.5</span>f); <span class="hljs-keyword">set</span>.addAnimation(translationX); <span class="hljs-keyword">set</span>.addAnimation(translationY); <span class="hljs-keyword">set</span>.addAnimation(alpha); <span class="hljs-keyword">set</span>.setDuration(<span class="hljs-number">500</span>); <span class="hljs-keyword">return</span> <span class="hljs-keyword">set</span>; } <span class="hljs-comment">//计算动画view在根部局中的坐标 添加到根部局中</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">addViewToAnimLayout</span>(final ViewGroup vg, final View view, <span class="hljs-keyword">int</span>[] location) { <span class="hljs-keyword">int</span> x = location[<span class="hljs-number">0</span>]; <span class="hljs-keyword">int</span> y = location[<span class="hljs-number">1</span>]; <span class="hljs-keyword">int</span>[] loc = <span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[<span class="hljs-number">2</span>]; vg.getLocationInWindow(loc); view.setX(x); view.setY(y-loc[<span class="hljs-number">1</span>]); vg.addView(view); } <span class="hljs-comment">//设置动画结束移除动画view </span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setAnim</span>(final View v, <span class="hljs-keyword">int</span>[] start_location) { addViewToAnimLayout(anim_mask_layout, v, start_location); Animation <span class="hljs-keyword">set</span> = createAnim(start_location[<span class="hljs-number">0</span>],start_location[<span class="hljs-number">1</span>]); <span class="hljs-keyword">set</span>.setAnimationListener(<span class="hljs-keyword">new</span> Animation.AnimationListener() { @Override <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onAnimationStart</span>(Animation animation) { } @Override <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onAnimationEnd</span>(final Animation animation) { <span class="hljs-comment">//直接remove可能会因为界面仍在绘制中成而报错</span> mHanlder.postDelayed(<span class="hljs-keyword">new</span> Runnable() { @Override <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span>() { anim_mask_layout.removeView(v); } },<span class="hljs-number">100</span>); } @Override <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onAnimationRepeat</span>(Animation animation) { } }); v.startAnimation(<span class="hljs-keyword">set</span>); }</code>
底部弹出购物车清单
底部弹出的效果大家一定都很熟悉了,几回每个项目中都会用的到,官方没有提供简单的控件实现,一般都需要自己写,不过要做到简单流畅,便于移植推荐使用第三方库,这里向大家推荐一个bottomsheet
集成简单,效果多样这里简单介绍一下使用方法
集成
<code class="hljs bash has-numbering"> compile <span class="hljs-string">'com.flipboard:bottomsheet-core:1.5.1'</span></code><ul class="pre-numbering" style=""><li>1</li></ul><ul class="pre-numbering" style=""><li>1</li></ul>
使用
xml中使用BottomSheetLayout包裹弹出view时候的背景布局,BottomSheetLayout继承自帧布局
<code class="hljs avrasm has-numbering"><<span class="hljs-keyword">com</span><span class="hljs-preprocessor">.flipboard</span><span class="hljs-preprocessor">.bottomsheet</span><span class="hljs-preprocessor">.BottomSheetLayout</span> xmlns:android=<span class="hljs-string">"http://schemas.android.com/apk/res/android"</span> android:id=<span class="hljs-string">"@+id/bottomSheetLayout"</span> android:layout_width=<span class="hljs-string">"match_parent"</span> android:layout_height=<span class="hljs-string">"match_parent"</span>> <LinearLayout android:orientation=<span class="hljs-string">"horizontal"</span> android:layout_width=<span class="hljs-string">"match_parent"</span> android:layout_height=<span class="hljs-string">"match_parent"</span>> <android<span class="hljs-preprocessor">.support</span><span class="hljs-preprocessor">.v</span>7<span class="hljs-preprocessor">.widget</span><span class="hljs-preprocessor">.RecyclerView</span> android:layout_width=<span class="hljs-string">"100dp"</span> android:id=<span class="hljs-string">"@+id/typeRecyclerView"</span> android:layout_height=<span class="hljs-string">"match_parent"</span>> </android<span class="hljs-preprocessor">.support</span><span class="hljs-preprocessor">.v</span>7<span class="hljs-preprocessor">.widget</span><span class="hljs-preprocessor">.RecyclerView</span>> <se<span class="hljs-preprocessor">.emilsjolander</span><span class="hljs-preprocessor">.stickylistheaders</span><span class="hljs-preprocessor">.StickyListHeadersListView</span> android:layout_width=<span class="hljs-string">"match_parent"</span> android:background=<span class="hljs-string">"#fff"</span> android:id=<span class="hljs-string">"@+id/itemListView"</span> android:layout_height=<span class="hljs-string">"match_parent"</span>> </se<span class="hljs-preprocessor">.emilsjolander</span><span class="hljs-preprocessor">.stickylistheaders</span><span class="hljs-preprocessor">.StickyListHeadersListView</span>> </LinearLayout> </<span class="hljs-keyword">com</span><span class="hljs-preprocessor">.flipboard</span><span class="hljs-preprocessor">.bottomsheet</span><span class="hljs-preprocessor">.BottomSheetLayout</span>></code>
代码中使用很简单
<code class="hljs cs has-numbering"> <span class="hljs-comment">//弹出View bottomSheet即是要弹出的view</span> bottomSheetLayout.showWithSheetView(bottomSheet); <span class="hljs-comment">//代码隐藏view (点击弹出view以外的地方可以隐藏弹出的view,向下滑动也可以)</span> bottomSheetLayout.dismissSheet(); </code>
数据的同步
同步数据,控制界面刷新应该是新手最容易绕弯的地方了,其实只要仔细一点也不难,这里简单提供一种思路(并不一定适合你的项目).<code class="hljs cs has-numbering"> <span class="hljs-comment">//商品列表</span> <span class="hljs-keyword">private</span> ArrayList<GoodsItem> dataList; <span class="hljs-comment">//分类列表</span> <span class="hljs-keyword">private</span> ArrayList<GoodsItem> typeList; <span class="hljs-comment">//已选择的商品</span> <span class="hljs-keyword">private</span> SparseArray<GoodsItem> selectedList; <span class="hljs-comment">//用于记录每个分组选择的数目</span> <span class="hljs-keyword">private</span> SparseIntArray groupSelect;</code>
SparseArray这个类其实就是 HashMap< Integer,Object >
不过SparseArray既可以根据key查找Value,也可以根据位置查找value,性能比HashMap高,是官方推荐的替代类,
同样SparseIntArray 其实是HashMap< Integer,Integer> 的替代者。
Activity里实现了下面几个方法,用于数据统一管理
列表中显示的商品购买数量统一从activity获取,商品的加减统一调用Activity的方法然后notifiDatasetChanged,由于代码不少具体的还是看源码吧
<code class="hljs java has-numbering"> <span class="hljs-javadoc">/** * Item代表商品的购买数量加一 *<span class="hljs-javadoctag"> @param</span> item *<span class="hljs-javadoctag"> @param</span> refreshGoodList 是否刷新商品list */</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">add</span>(GoodsItem item,<span class="hljs-keyword">boolean</span> refreshGoodList){ <span class="hljs-keyword">int</span> groupCount = groupSelect.get(item.typeId); <span class="hljs-keyword">if</span>(groupCount==<span class="hljs-number">0</span>){ groupSelect.append(item.typeId,<span class="hljs-number">1</span>); }<span class="hljs-keyword">else</span>{ groupSelect.append(item.typeId,++groupCount); } GoodsItem temp = selectedList.get(item.id); <span class="hljs-keyword">if</span>(temp==<span class="hljs-keyword">null</span>){ item.count=<span class="hljs-number">1</span>; selectedList.append(item.id,item); }<span class="hljs-keyword">else</span>{ temp.count++; } update(refreshGoodList); } <span class="hljs-javadoc">/** * Item商品的购买数量减一 *<span class="hljs-javadoctag"> @param</span> item *<span class="hljs-javadoctag"> @param</span> refreshGoodList 是否刷新商品list */</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">remove</span>(GoodsItem item,<span class="hljs-keyword">boolean</span> refreshGoodList){ <span class="hljs-keyword">int</span> groupCount = groupSelect.get(item.typeId); <span class="hljs-keyword">if</span>(groupCount==<span class="hljs-number">1</span>){ groupSelect.delete(item.typeId); }<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(groupCount><span class="hljs-number">1</span>){ groupSelect.append(item.typeId,--groupCount); } GoodsItem temp = selectedList.get(item.id); <span class="hljs-keyword">if</span>(temp!=<span class="hljs-keyword">null</span>){ <span class="hljs-keyword">if</span>(temp.count<<span class="hljs-number">2</span>){ selectedList.remove(item.id); }<span class="hljs-keyword">else</span>{ item.count--; } } update(refreshGoodList); } <span class="hljs-javadoc">/** * 刷新界面 总价、购买数量等 *<span class="hljs-javadoctag"> @param</span> refreshGoodList 是否刷新商品list */</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">update</span>(<span class="hljs-keyword">boolean</span> refreshGoodList){ ... } <span class="hljs-comment">//根据商品id获取当前商品的采购数量</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getSelectedItemCountById</span>(<span class="hljs-keyword">int</span> id){ GoodsItem temp = selectedList.get(id); <span class="hljs-keyword">if</span>(temp==<span class="hljs-keyword">null</span>){ <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; } <span class="hljs-keyword">return</span> temp.count; } <span class="hljs-comment">//根据类别Id获取属于当前类别的数量</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getSelectedGroupCountByTypeId</span>(<span class="hljs-keyword">int</span> typeId){ <span class="hljs-keyword">return</span> groupSelect.get(typeId); }</code>
具体逻辑还是看代码吧,也许有更简单的实现。。。
Demo下载地址,下载到的文件是个AS module,你可以在自己新建的工程中Import Module.
http://download.csdn.net/detail/w804518214/9539602
相关文章推荐
- Android仿外卖购物车的实现
- Android仿外卖购物车的实现
- Android仿外卖购物车的实现
- android实现蘑菇街购物车动画效果
- Android 实现蘑菇街购物车动画效果
- Android购物车初步实现1(UI篇)
- Android仿外卖购物车
- android 实现底部菜单并且实现购物车的提醒效果
- Android开发-实现pulltorefresh上类似购物车加减方法和EditText焦点问题的解决方法
- Android高阶UI之FlowLayout流布局实现加入购物车标签选择
- android添加购物车动画实现
- Android实现仿淘宝购物车增加和减少商品数量功能demo示例
- Android 实现购物车动画效果
- Android 购物车功能的实现
- android购物车的实现
- Android高阶UI之加入购物车选择颜色、尺码实现
- 【转】Android 实现蘑菇街购物车动画效果
- Android实现的仿淘宝购物车demo示例
- android添加购物车动画实现
- 由浅入深理解Android中的回调机制(二)【实现简易购物车功能】