1. 掌握bottomSheet,开发购物车
l 项目效果
l 控件运行效果
[开源控件库]https://github.com/Flipboard/bottomsheet
第三方开源控件库,可以快速实现类似底部菜单的效果(类似安全卫士-归属地风格选择Dialog)
使用步骤
>1.依赖
compile'com.flipboard:bottomsheet-commons:1.5.1'
compile 'com.flipboard:bottomsheet-core:1.5.1'
>2.布局页面内容
layout/activity_main.xml
<?xml version="1.0"encoding="utf-8"?>
<com.flipboard.bottomsheet.BottomSheetLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/bottom_sheet_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:onClick="show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="三"/>
</LinearLayout>
</com.flipboard.bottomsheet.BottomSheetLayout>
>3.布局弹出内容
layout/pop_sheet.xml
<?xml version="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFF000"
android:orientation="vertical"
tools:context="com.itheima.app_bottom.MainActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="条目一"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="条目二"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="条目三"/>
</LinearLayout>
>4.编写显示与隐藏逻辑
public classMainActivityextends AppCompatActivity {
privateBottomSheetLayoutbottomSheetLayout;
privateView popView;
@Override
protected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//查找控件
bottomSheetLayout= (BottomSheetLayout) findViewById(R.id.bottom_sheet_layout);
}
public voidshow(View view) {
//判断弹出内容是否可见
if(bottomSheetLayout.isSheetShowing()) {
//可见则隐藏
bottomSheetLayout.dismissSheet();
} else {
if(popView== null) {
popView= LayoutInflater.from(this).inflate(R.layout.pop_sheet,bottomSheetLayout,false);
}
//不可见则显示 ,对popView进行是否为空判断可以减少view的创建
bottomSheetLayout.showWithSheetView(popView);
}
}
}
2. 掌握stickylistheaders,使用tabs滑动固定
l 运行效果
【开源控件库】https://github.com/emilsjolander/StickyListHeaders
将元素按照typeId进行组,相同typeId的元素在一个分组。
组视图可以上滑到达顶部固定住(类似联系人效果)
>1.依赖
compile'se.emilsjolander:stickylistheaders:2.7.0'
>2.布局UI
layout/activity_main.xml
<?xml version="1.0"encoding="utf-8"?>
<se.emilsjolander.stickylistheaders.StickyListHeadersListViewxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/stick_headers_lv"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
layout/item_header.xml
<?xml version="1.0"encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.itheima.appstickyheader.MainActivity">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:text="标题"
android:padding="10dp"
android:background="#FFF000"
android:layout_height="wrap_content"/>
</RelativeLayout>
layout/item.xml
<?xml version="1.0"encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.itheima.appstickyheader.MainActivity">
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:text="条目"
android:textSize="22sp"
android:padding="10dp"
android:layout_height="wrap_content"/>
</RelativeLayout>
>3.创建带有typeId的记录
//数据模型
public classInfo {
private inttypeId;
privateString typeName;
privateString content;
//typeId相同的id代表同一个组的元素
//typeName组名
//content元素名
publicInfo(inttypeId, String typeName, String content) {
this.typeId= typeId;
this.typeName= typeName;
this.content= content;
}省略get/set
>4使用适配器进行初始化
public classMainActivityextends AppCompatActivity {
@InjectView(R.id.stick_headers_lv)
StickyListHeadersListViewstickHeadersLv;
privateList<Info>mData = null;
@Override
protected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.inject(this);
mData= new ArrayList<>();
for(inti = 0; i <5; i++) {
for(intj = 0; j <10; j++) {
mData.add(newInfo(i, "组名" + i,"成员" + i + "--"+ j));
}
}
MyAdapter adapter =new MyAdapter();
stickHeadersLv.setAdapter(adapter);
}
>5.实现适配器
private classMyAdapterextends BaseAdapter implements StickyListHeadersAdapter {
//组
@Override
publicView getHeaderView(intposition, View convertView, ViewGroup parent) {
if(convertView ==null) {
convertView = View.inflate(parent.getContext(), R.layout.item_header,null);
}
TextView text = (TextView) convertView.findViewById(R.id.title);
Info info =mData.get(position);
text.setText(info.getTypeName());
returnconvertView;
}
//元素
@Override
publicView getView(intposition, View convertView, ViewGroup parent) {
if(convertView ==null) {
convertView = View.inflate(parent.getContext(), R.layout.item,null);
}
TextView text = (TextView) convertView.findViewById(R.id.text);
Info info =mData.get(position);
text.setText(info.getContent());
returnconvertView;
}
//按typeid分组
@Override
public longgetHeaderId(intposition) {
returnmData.get(position).getTypeId();
}
@Override
public intgetCount() {
returnmData.size();
}
3. 进入到商铺页面,选餐
3.1. 给条目添加点击事件,Intent打开BusinessActivity
com.itheima.app_.ui.adapter.HeaderAdapter
>1.添加点击事件,意图打开页面
在com.itheima.app_.ui.adapter.HeaderAdapter#onBindViewHolder方法中
//添加点击事件跳转到商铺页面
hd.itemView.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View v) {
Intent intent=newIntent(v.getContext(),BussinessActivity.class);
intent.putExtra("item",item);
v.getContext().startActivity(intent);
}
});
注意事项:
Intent传递javaBean要求这个对象序列化
l BodyInfo序列化
l SellerInfo序列化
3.2. 创建BusinessActivity界面
>1.配置
<activityandroid:name=".ui.activity.BussinessActivity"/>
>2.创建页面
public classBussinessActivityextends BaseActivity {
@Override
protected voidonCreate(@NullableBundle savedInstanceState) {
super.onCreate(savedInstanceState);
//给手机状态栏着色
initSystemBar()
}
>3.布局UI
3.3. 整体界面UI分析(引入BottomSheet)
//底部弹出窗体
compile'com.flipboard:bottomsheet-commons:1.5.1'
compile'com.flipboard:bottomsheet-core:1.5.1'
layout/activity_bussiness.xml
<?xml version="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fitsSystemWindows="true"
android:clipToPadding="false">
<!--内容-->
<com.flipboard.bottomsheet.BottomSheetLayout
android:id="@+id/bottom_sheet_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<!--BottomSheetLayout的子元素必须为1-->
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">
<!--标题-->
<includelayout="@layout/include_titlebar"/>
<!--商品评价商家-->
<includelayout="@layout/include_tabs_viewpager"/>
</LinearLayout>
</com.flipboard.bottomsheet.BottomSheetLayout>
<!--底部-->
<includelayout="@layout/include_bottom"/>
</LinearLayout>
可以使用include知识点,将布局好的内容引入,这样页面结构更清析
3.4. 使用include引入标题
layout/include_titlebar.xml
<?xml version="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#f6f89191"
android:orientation="horizontal"
android:paddingBottom="10dp"
android:paddingTop="25dp">
<ImageButton
android:id="@+id/ib_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:background="@mipmap/ic_back"/>
<TextView
android:id="@+id/tv_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_weight="1"
android:maxLines="1"
android:text="标题--"
android:textColor="#fff"
android:textSize="20sp"
android:textStyle="bold"/>
<ImageButton
android:id="@+id/ib_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="10dp"
android:background="@mipmap/ic_menu"/>
</LinearLayout>
3.5. 使用include引入tablayout与viewpager
layout/include_tabs_viewpager.xml
<?xml version="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.TabLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorColor="#00f"
app:tabIndicatorHeight="4dp"
app:tabSelectedTextColor="#00f"
app:tabTextColor="#000"/>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
属性解释
app:tabIndicatorColor="#00f" tab底部选中的颜色标识
app:tabIndicatorHeight="4dp" 标识的高度
app:tabSelectedTextColor="#00f" 选中tab文字的颜色
app:tabTextColor="#000" 没有选中tab文字的颜色
3.6. 使用include引入底部购物车
layout/include_shop_cart.xml
<?xml version="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/bottom"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#aa000000"
android:clickable="true"
android:gravity="center_vertical"
android:onClick="onClick"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="50dp"
android:layout_height="match_parent">
<ImageView
android:id="@+id/img_cart"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_centerInParent="true"
android:src="@mipmap/icon_cart"/>
<TextView
android:id="@+id/tv_select_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
android:background="@drawable/circle_red"
android:gravity="center"
android:text="1"
android:textColor="#fff"
android:textSize="12sp"
android:visibility="gone"/>
</RelativeLayout>
<TextView
android:id="@+id/tv_count_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:gravity="center_vertical"
android:text="¥0"
android:textColor="#fff"
android:textSize="14sp"/>
<TextView
android:id="@+id/tv_delivery_fee"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginRight="5dp"
android:layout_weight="1"
android:gravity="center"
android:text="另需配送费¥4"
android:textColor="#fff"
android:textSize="14sp"/>
<TextView
android:id="@+id/tv_send_price"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginRight="10dp"
android:gravity="center"
android:text="¥100元起送"
android:textColor="#fff"
android:textSize="14sp"/>
<TextView
android:id="@+id/tv_submit"
android:layout_width="90dp"
android:layout_height="match_parent"
android:background="#22c222"
android:clickable="true"
android:gravity="center"
android:onClick="onClick"
android:text="去结算"
android:textColor="#fff"
android:textSize="18sp"
android:visibility="gone"/>
</LinearLayout>
3.7. 使用BusinessViewHolder缓存所有控件
l 以下代码使用butterknife自动生成不需要手动编码
把所有元素放到hd,方便以后使用减少activity代码
//页面控件的缓存BusinessViewHolder
static classBusinessViewHolder {
@InjectView(R.id.ib_back)
ImageButton ibBack;
@InjectView(R.id.tv_title)
TextView tvTitle;
@InjectView(R.id.ib_menu)
ImageButton ibMenu;
@InjectView(R.id.tab_layout)
TabLayout tabLayout;
@InjectView(R.id.viewpager)
ViewPager viewpager;
@InjectView(R.id.bottom_sheet_layout)
BottomSheetLayoutbottomSheetLayout;
@InjectView(R.id.img_cart)
ImageView imgCart;
@InjectView(R.id.tv_select_num)
TextView tvSelectNum;
@InjectView(R.id.tv_count_price)
TextView tvCountPrice;
@InjectView(R.id.tv_delivery_fee)
TextView tvDeliveryFee;
@InjectView(R.id.tv_send_price)
TextView tvSendPrice;
@InjectView(R.id.tv_submit)
TextView tvSubmit;
@InjectView(R.id.bottom)
LinearLayout bottom;
BusinessViewHolder(View view) {
ButterKnife.inject(this, view);
}
}
3.8. 取Intent数据显示在标题上
//初始化页面的控件并缓存在ViewHolder里面
View view = View.inflate(this, R.layout.activity_bussiness,null);
mHd = newBusinessViewHolder(view);
setContentView(view);
//从intent里面获取条目数据
Intent intent = getIntent();
HomeData.BodyInfo item = (HomeData.BodyInfo) intent.getSerializableExtra("item");
//设置标题
mHd.tvTitle.setText(item.seller.name);
//添加返回关闭
mHd.ibBack.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View v) {
finish();
}
});
3.9. 初始化TabLayout与ViewPager
l 运行效果
>1.初始化
l 给Veiwpager设置一个适配器
l 给TabLayout设置一个viewPager
l 如果TabLayout不显示标题重写getPageTitle方法
//初始化tab
String[] names =new String[]{"商品","评价","商家"};
for (String name : names) {
TabLayout.Tab tab =mHd.tabLayout.newTab().setText(name);
mHd.tabLayout.addTab(tab);
}
//初始化ViewPager,包含三个标题对应的三个Fragment页面
BusinessActivityVpAdapter adapter =new BusinessActivityVpAdapter(getSupportFragmentManager());
mHd.viewpager.setAdapter(adapter);
//绑定指示器与ViewPager,让用户点击标题切换viewpager,切换viewpager可以同步标题
mHd.tabLayout.setupWithViewPager(mHd.viewpager);
>2.创建适配器
com.itheima.app_.ui.adapter.BusinessActivityVpAdapter
public classBusinessActivityVpAdapterextends FragmentPagerAdapter {
//页面集合 装载Fragment页面
privateList<Fragment>mPages = newArrayList<>();
privateString[]mNames = newString[]{"商品","评价","商家"};
publicBusinessActivityVpAdapter(FragmentManager fm) {
super(fm);
mPages.add(newGoodFragment());
mPages.add(newCommentFragment());
mPages.add(newBusinessFragment());
}
//一定要重写,否则指示器获取不到标题
@Override
publicCharSequence getPageTitle(intposition) {
returnmNames[position];
}
//返回页面
@Override
publicFragment getItem(intposition) {
returnmPages.get(position);
}
//表示 vp的页面数
@Override
public intgetCount() {
returnmPages.size();
}
}
以上使用到的Fragment页面与布局
>4.控件购物车显示逻辑
购物车只在ViewPager的下标为0时才显示,其它下标均隐藏
//添加页面切换事件处理
mHd.viewpager.addOnPageChangeListener(listener);
private ViewPager.OnPageChangeListenerlistener = newViewPager.OnPageChangeListener() {
@Override
public voidonPageSelected(intposition) {
//页号为0显示底部购物车 其它隐藏
mHd.bottom.setVisibility(position==0?View.VISIBLE:View.GONE);//使用表达式可以简化代码
}
@Override
public voidonPageScrolled(intposition,float positionOffset,int positionOffsetPixels) {
}
@Override
public voidonPageScrollStateChanged(intstate) {
}
};
@Override
protected voidonDestroy() {
super.onDestroy();
mHd.viewpager.removeOnPageChangeListener(listener);
}
4. 获取商铺页面的商品信息
l 运行效果
4.1. UI布局分析
l 左侧是可以一个固定宽度,右侧使用权重。
l 两侧可以都是权重 例1:3
4.2. 编写GoodFragmentPresenter获取服务端数据
l 运行效果
>1.增加retrofit接口方法
com.itheima.app_.model.net.TakeOutApi
@GET(Contants.BUSINESS)
Call<ResponseData> getBusiness(@Query("sellerId")String sellerId);
>2.编写GoodFragmentPresenter核心逻辑
com.itheima.app_.presenter.GoodFragmentPresenter
//mvp 中的p是获取数据,处理线程的核心对象
public classGoodFragmentPresenterextends BasePresenter {
//View
privateGoodFragmentmView;
publicGoodFragmentPresenter() {
}
public voidsetView(GoodFragment view) {
this.mView= view;
}
public voidreset() {
this.mView= null;
}
//Module
privateBusinessDatadata;
public voidgetData(){
//调用v显示等待
this.mView.showLoading();
Call<ResponseData> call = HttpUtils2.getApi().getBusiness(BussinessActivity.sSellerId);
SimpleCallBack callBack=newSimpleCallBack(){
@Override
protected voidshowError(inti, RuntimeException e) {
super.showError(i, e);
//调用v显示出错提示
System.out.println(e.getMessage());
mView.showError(e.getMessage());
}
@Override
protected voidshowData(String json) {
super.showData(json);
//把json数据解析后显示在界面
BusinessData data= newGson().fromJson(json,BusinessData.class);
mView.showData(data);
}
};
call.enqueue(callBack);
}
}
l 可以在debug模式下获取json数据进行解析,解析的javaBean不用自己编写,使用gsonFromat自动生成
4.3. 使用dagger2管理GoodFragmentPresenter
>1.使用@module与@provides创建工厂
@Module
public classHomeFragmentModule {
@Provides
publicHomeFragmentPresenter providerPresneter() {
return newHomeFragmentPresenter();
}
}
>2.使用@component创建注入器
@Component(modules = {HomeFragmentModule.class})
public interfaceHomeFragmentComponent {
public voidinject(HomeFragment fragment);
}
>3.在GoodFragment使用@Inject注入presenter实例,注意实例不能为private,同时要点run按钮
@Inject
public GoodFragmentPresenterpresenter;
@Override
public voidonViewCreated(View view,@Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//获取当页面的id向服务端发送请求
//presenter = new GoodFragmentPresenter();
DaggerGoodFragmentComponent.builder().
goodFragmentModule(newGoodFragmentModule())
.build()
.inject(this);
presenter.setView(this);
presenter.getData();
}
4.4. 有了数据以后,即可编写数据显示
com.itheima.app_.ui.fragment.GoodFragment
>1.初始化recyclerView
public voidshowLoading() {
Toast.makeText(getContext(),"正在加载...", Toast.LENGTH_SHORT).show();
}
public voidshowError(String message) {
Toast.makeText(getContext(),"加载数据失败.", Toast.LENGTH_SHORT).show();
}
public voidshowData(BusinessData data) {
//列表的排列效果
goodTypes.setLayoutManager(newLinearLayoutManager(getContext()));
GoodTypeAdapter adapter=newGoodTypeAdapter(data.list);
goodTypes.addItemDecoration(newRecycleViewDivider(getContext(),LinearLayoutManager.VERTICAL));
goodTypes.setAdapter(adapter);
}
>2.recyclerView的显示关键在适配器。
1)编写holder与item视图
layout/item_type.xml
<?xml version="1.0"encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:clickable="true"
android:layout_height="wrap_content"
android:minHeight="80dp"
android:background="#b9dedcdc"
android:orientation="vertical">
<TextViewandroid:gravity="center"
android:id="@+id/tv_count"
android:layout_marginTop="5dp"
android:textColor="#fff"
android:text="1"
android:visibility="invisible"
android:layout_marginRight="5dp"
android:textSize="12sp"
android:background="@drawable/circle_red"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
/>
<TextView
android:layout_width="match_parent"
android:gravity="center"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:padding="5dp"
android:id="@+id/type"
android:text="种类1">
</TextView>
</RelativeLayout>
com.itheima.app_.ui.holder.GoodTypeHolder(holder代码不用自己写,可以通过butterknife生成)
public classGoodTypeHolderextends RecyclerView.ViewHolder {
@InjectView(R.id.tv_count)
public TextView tvCount;
@InjectView(R.id.type)
publicTextView type;
publicGoodTypeHolder(View itemView) {
super(itemView);
intlayoutId = R.layout.item_type;
ButterKnife.inject(this,itemView);
}
}
>3.有了hd就可以快速编写Adapter
com.itheima.app_.ui.adapter.GoodTypeAdapter
public classGoodTypeAdapterextends RecyclerView.Adapter<GoodTypeHolder> {
publicList<BusinessData.GoodType>mData;
publicGoodTypeAdapter(List<BusinessData.GoodType> list) {
mData=list;
}
//给rv创建条目的缓存holder
@Override
publicGoodTypeHolder onCreateViewHolder(ViewGroup parent,int viewType) {
// View view= View.inflate(parent.getContext(), R.layout.item_type,null);
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.item_type,parent,false);
GoodTypeHolder hd=newGoodTypeHolder(view);
returnhd;
}
privateInteger mSelectedPosition=0;//记录当前选中位置
//给每个条目赋值
@Override
public voidonBindViewHolder(GoodCategoryHolder holder,final int position) {
finalBusinessData.GoodType type =mData.get(position);
holder.type.setText(type.name);
//调整背景颜色
holder.itemView.setBackgroundColor(position==mSelectedPosition? Color.WHITE:Color.parseColor("#b9dedcdc"));
holder.itemView.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View v) {
//选中的使用白色背景 未选中的灰色
mSelectedPosition=position;
//刷新
notifyDataSetChanged();
}
});
}
//给rv提供数据
@Override
public intgetItemCount() {
returnmData.size();
}
}
>4.编写类别选中
l 同上方红色代码
4.5. 完成左侧类别,即可显示右侧分组列表
>1.在获取数据后将数据按照headId进行排列
@Override
protected voidshowData(String json) {
super.showData(json);
//把json数据解析后显示在界面
BusinessData data =new Gson().fromJson(json, BusinessData.class);
mGoodDatas= new ArrayList<>();
//遍历商品类别
List<BusinessData.GoodType> list = data.list;
for(intheadId =0; headId < list.size(); headId++) {
//从类别中取出每个商品信息
BusinessData.GoodType type = list.get(headId);
//保存组名
String groupName = type.name;
List<BusinessData.GoodType.GoodInfo> goodList = type.list;
//将商品信息再进行分组,就得给每个商品设置headId
for(BusinessData.GoodType.GoodInfo info : goodList) {
GoodData eachGood =new GoodData(headId, groupName, info);
//添加进集合
mGoodDatas.add(eachGood);
}
}
mView.showData(list,mGoodDatas);
}
>2.用到的GoodData对象包含headId
com.itheima.app_.model.bean.GoodData
public classGoodData {
public intheadId;
publicString typeName;
publicBusinessData.GoodType.GoodInfoinfo;
publicGoodData(intheadId, String typeName, BusinessData.GoodType.GoodInfo info) {
this.headId= headId;
this.typeName= typeName;
this.info= info;
}
}
>3.编写显示逻辑
com.itheima.app_.ui.fragment.GoodFragment#showData
public voidshowData(List<BusinessData.GoodType> list, List<GoodData> goodDatas) {
//列表的排列效果
goodTypes.setLayoutManager(newLinearLayoutManager(getContext()));
finalGoodCategoryAdapter adapter =new GoodCategoryAdapter(list);
goodTypes.addItemDecoration(newRecycleViewDivider(getContext(), LinearLayoutManager.VERTICAL));
goodTypes.setAdapter(adapter);
//分组列表
finalGoodStickListAdapter goodStickListAdapter =new GoodStickListAdapter(goodDatas);
goodList.setAdapter(goodStickListAdapter);
AbsListView.OnScrollListener scollListener =new AbsListView.OnScrollListener() {
@Override
public voidonScrollStateChanged(AbsListView view,int scrollState) {
}
@Override
public voidonScroll(AbsListView view,int firstVisibleItem,int visibleItemCount,int totalItemCount) {
//获取当前显示列表显示第一项对应的position; 拿这个position跟左侧选中的类别的headId比较
GoodData item = goodStickListAdapter.getItem(firstVisibleItem);
if(item.headId!= adapter.getSelectedPosition()) {
adapter.setSelectedPosition(item.headId);
}
}
};
goodList.setOnScrollListener(scollListener);
}
>4.滑动商品列表,切换商品类别
同上方红色字体代码 OnScrollListener 基本逻辑是拿出商品列表的顶部的元素查询headId.将左侧的商品类别
数据调到选中位置
>5.选中左侧商品类别
com.itheima.app_.ui.adapter.GoodCategoryAdapter#getSelectedPosition
//获取选中组
publicInteger getSelectedPosition() {
returnmSelectedPosition;
}
//修改选中组
public voidsetSelectedPosition(intposition) {
mSelectedPosition=position;
notifyDataSetChanged();
}
private Integer mSelectedPosition=0;//记录当前选中位置
>6.点击左侧商品类别切换右侧商品列表(引入eventBus3.0)
在 com.itheima.app_.ui.adapter.GoodCategoryAdapter#onBindViewHolder
holder.itemView.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View v) {
//选中的使用白色背景 未选中的灰色
mSelectedPosition=position;
//刷新
notifyDataSetChanged();
EventBus.getDefault().post(mSelectedPosition);//发送id给GoodFragment要求商品列表
//滚动到该类别下的第一个元素 比如id为101,那个显示13.9特价套餐的第一个商品
}
});
l 这里为什么要引入eventbus3.0?
因为在这里写点击事件要求GoodFragment切换rv.
这样要用到presenter与rv,不如把选中下标以消息的方式发送出去,在GoodFragment
页面接收参数切换选中位置,可以不受参数限制。
具体用法:
1)依赖eventBus
//使用eventbus3.0方便参数传递
compile 'org.greenrobot:eventbus:3.0.0'
2)在GoodFragment页面注册与处理
EventBus.getDefault().register(this);
//接收点击的商品类型的id
@Subscribe(threadMode = ThreadMode.MAIN)
public voidonEvent(Integer groupId) {
//选择 typeId组的第一个元素
intpostion=presenter.findPositionForGroupFirst(groupId);
goodList.setSelection(postion);
}
3)在GoodFragment销毁后移除
EventBus.getDefault().unregister(this);
5. 购物车页面
5.1. 购物车特效-贝塞尔曲线
l 购物车特效原理:
1.从添加按钮获取开始坐标
2.从购物车图标获取结束坐标
3.打气一个视图,添加属性动画ObjectAnimator(缩小),ValueAnimator(路线)
4.动画开始时添加该视图,动画结束删除该视图
5.运动路径使用TypeEvaluator与贝塞尔函数计算
>1.创建布局UI
layout/activity_main.xml
<?xml version="1.0"encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rl"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="cn.c.com.beziercurveanimater.MainActivity">
<cn.c.com.beziercurveanimater.ex.MyCartAnimView
android:id="@+id/move"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<Button
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:onClick="buy"
android:text="+"/>
<ImageView
android:id="@+id/cart"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:src="@drawable/gouwuche"/>
</RelativeLayout>
移动控件(项目中不是把条目上的+按钮进行移动,而是添加一个新view进行移动)
<?xml version="1.0"encoding="utf-8"?>
<ImageViewxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="50dp"
android:layout_height="50dp"
android:orientation="vertical"
android:src="@drawable/coin1"
/>
>2.初始化事件
cn.c.com.beziercurveanimater.MainActivity
public classMainActivityextends AppCompatActivity {
privateImageViewcart;
privateMyCartAnimViewanimview;
@Override
protected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cart= (ImageView) findViewById(R.id.cart);
animview= (MyCartAnimView) findViewById(R.id.move);
}
public voidbuy(View view) {
animview.startAnim(view,cart, R.layout.cart_anim);
}
}
>3.自定义控件CartAnimView
public classMyCartAnimViewextends FrameLayout {
publicMyCartAnimView(Context context) {
this(context,null,0);
}
publicMyCartAnimView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
publicMyCartAnimView(Context context, AttributeSet attrs,int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
//主要是三个元素 一个ImageView按照点击 的按钮位置 以抛物线的方式 滑动到 购物车控件位置
//1.重写onLayout方法 初始化当前布局的坐标
privatePointF mLocation = newPointF();//坐标对象包含x,y
@Override
protected voidonLayout(booleanchanged,int left, inttop, int right,int bottom) {
super.onLayout(changed, left, top, right, bottom);
int[] l =new int[2];
getLocationInWindow(l);
mLocation.set(l[0], l[1]);//初始化布局位置
}
//2.编写开始动画方法
//3.保存移动控件的坐标
public voidstartAnim(finalView startView,final View endView, final int moveLayoutId) {
//使用属性动画创建 移动与缩放效果
AnimatorSet set =new AnimatorSet();
//路径动画怎么处理?1.确定开始位置 2.结束位置 3.中间运行坐标使用贝塞尔曲线计算
//1.开始位置
PointF startF=newPointF();
int[] startLoc=new int[2];
startView.getLocationInWindow(startLoc);
startF.set(startLoc[0]-mLocation.x,startLoc[1]-mLocation.y);
//2.结束位置
PointF endF=newPointF();
if(endView ==null) {
//使用左下角默认作为购物车控件位置
endF.set(0,getMeasuredHeight());
}else
{//计算购物车坐标
int[] mEndLoc=new int[2];
endView.getLocationInWindow(mEndLoc);
//相对布局坐标
endF.set(mEndLoc[0]-mLocation.x,mEndLoc[1]-mLocation.y);
}
//3.移动控件
final View moveView= LayoutInflater.from(getContext()).inflate(moveLayoutId,this,false);
//创建坐标变化函数
TypeEvaluator evaluator=newMyBezierEvaluator();
ValueAnimator pathAnim = ObjectAnimator.ofObject(evaluator,startF,endF);
pathAnim.addUpdateListener(newValueAnimator.AnimatorUpdateListener() {
@Override
public voidonAnimationUpdate(ValueAnimator animation) {
PointF newF= (PointF) animation.getAnimatedValue();
//更新给坐标
moveView.setX(newF.x);
moveView.setY(newF.y);
}
});
set.playTogether(
ObjectAnimator.ofFloat(moveView,"scaleX",1.0f,0.3f),//缩小
ObjectAnimator.ofFloat(moveView,"scaleY",1.0f,0.3f),//缩小
pathAnim
);
// 现在这个moveView还不属于当前布局内的元素,所以不能显示在当前布局,可以在特效开始前添加
//特效结束后删除
set.addListener(newAnimator.AnimatorListener() {
@Override
public voidonAnimationStart(Animator animation) {
MyCartAnimView.this.addView(moveView);//动画开始添加
}
@Override
public voidonAnimationEnd(Animator animation) {
MyCartAnimView.this.removeView(moveView);//动画结束 删除
}
@Override
public voidonAnimationCancel(Animator animation) {
}
@Override
public voidonAnimationRepeat(Animator animation) {
}
});
set.setDuration(1000);
set.start();
}
//创建曲线函数
private classMyBezierEvaluatorimplements TypeEvaluator<PointF> {
@Override
publicPointF evaluate(floatfraction, PointF startValue, PointF endValue) {
System.out.println("fraction="+fraction);
//返回变化的轨迹坐标
PointF newF=newPointF((startValue.x+endValue.x)/2,0);
returnBezierCurve.bezier(fraction,startValue,newF ,endValue);
}
}
}
5.2. 创建购物车对象Cart
一进页面显示获取项目的单例购物车对象,取出针对卖家添加的商品内容
,包括数量,价格,配送费,起送价(总价超过起送价显示结算)
所以要深刻里面 商品购物项与 购物车之间的包含关系
>1.com.itheima.app_.model.bean.CartItem 购物项
public classCartItem {
privateString sellerId;//商铺id
private inttypeId;//类别id
private intgoodsId;//商品id
private intcount;//商品数量
private floatpriceSingle;//单品价格
privateString goodName;//商品名称
//省略get set
}
>2.com.itheima.app_.model.bean.Cart 购物
public classCart {
public static final intADD =1;
public static final intMINU = -1;
private staticCart sCart;
privateCart() {
}
public staticCart getCart() {
if(sCart== null) {
sCart= newCart();
}
returnsCart;
}
//一个购物车包含多个购物项,是集合与元素的关系
privateList<CartItem>mList = newArrayList<>();
l 为什么是单例?
一个app只有一个购物车,多个购物车实例会引起结算问题,试想你推送一辆购物车去收银台结算容易,还是100辆容易?
>3.支持条目的上增加与减少按钮的数据处理
//添加元素
public voidadd(String sellerId, inttypeId,intgoodsId,String goodName,floatpriceSingle) {
CartItem result = findItemByGoodId(goodsId);
if(result ==null) {
CartItem cartItem =new CartItem( sellerId, typeId, goodsId, goodName,priceSingle);
mList.add(cartItem);
}
}
//更新元素
public voidupdate(intgoodsId,int operate) {
CartItem result = findItemByGoodId(goodsId);
if(result !=null) {
if(operate ==ADD) {
result.setCount(result.getCount() +1);
} else {
result.setCount(result.getCount() -1);
if(result.getCount() ==0) {
mList.remove(result);
}
}
}
}
//查找元素
publicCartItem findItemByGoodId(intgoodId) {
for(CartItem item :mList) {
if(item.getGoodsId() == goodId) {
returnitem;
}
}
return null;
}
//查看指定的卖家sellerId在购物车里面的数量 决定 是否要显示-号与数量
public intfindCountBySellerId(String sellerId) {
intcountSelect =0;
for(CartItem item :mList) {
if(TextUtils.equals(sellerId, item.getSellerId())) {
countSelect += item.getCount();
}
}
returncountSelect;
}
//获取指定商家的总价
public floatfindPriceCountBySellerId(String sellerId) {
floatcountPrice =0;
for(CartItem item :mList) {
if(TextUtils.equals(sellerId, item.getSellerId())) {
countPrice += (item.getCount()*item.getPriceSingle());
}
}
returncountPrice;
}
l 建议使用Android4Junit进行测试,以确保购物车没有bug,后面就可以由条目调用
5.3. 点击+号添加-号减少
com.itheima.app_.ui.adapter.GoodStickListAdapter#getView
hd.tvName.setText(info.name);//商品名
hd.tvContain.setText(info.form);//组成
hd.tvSaleCount.setText("月销售出"+ info.monthSaleNum);//月销售
hd.tvNewprice.setText("$"+ info.newPrice);//新价格
hd.tvOldprice.setText("$"+ info.oldPrice);//旧价格
hd.tvOldprice.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG);//删除实线
//加载图片
Picasso.with(convertView.getContext()).load(info.icon).into(hd.ivIcon);
finalGoodItemViewHolder currHd = hd;
//添加商品
hd.ibAdd.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View v) {
//添加进购物车
GoodData goodData =mData.get(position);
CartItem item = Cart.getCart().findItemByGoodId(info.id);
if(item ==null) {
Cart.getCart().add(BussinessActivity.sSellerId, goodData.headId, goodData.info.id,info.name,info.newPrice);
} else {
Cart.getCart().update(goodData.info.id, Cart.ADD);
}
//刷新
notifyDataSetChanged();
Message msg =new Message();
msg.what= Cart.ADD;
msg.obj= v;
EventBus.getDefault().post(msg);
}
});
//删除操作
hd.ibMinus.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View v) {
GoodData goodData =mData.get(position);
Cart.getCart().update(goodData.info.id, Cart.MINU);
//刷新
notifyDataSetChanged();
Message msg =new Message();
msg.what= Cart.MINU;
msg.obj= null;//删除不需要抛物线动画
EventBus.getDefault().post(msg);
}
});
//刷新列表 上的-号状态与数量
updateCountMinuState(hd, info);
returnconvertView;
}
private voidupdateCountMinuState(GoodItemViewHolder hd, BusinessData.GoodType.GoodInfo info) {
CartItem item = Cart.getCart().findItemByGoodId(info.id);
if(item ==null || item.getCount() ==0) {
hd.ibMinus.setVisibility(View.INVISIBLE);
hd.tvCount.setVisibility(View.INVISIBLE);
hd.tvCount.setText("0");
} else{
hd.ibMinus.setVisibility(View.VISIBLE);
hd.tvCount.setVisibility(View.VISIBLE);
hd.tvCount.setText(item.getCount() +"");
}
}
5.4. +与-操作没问题后,再提交界面要求更新底部购物车状态
>1.一个页面要接收eventbus传递的参数
EventBus.getDefault().register(this);
EventBus.getDefault().unregister(this);
>2.添加接收方法接收参数,注意方法建议以onEvent命名
@Subscribe(threadMode = ThreadMode.MAIN)
public voidonEvent(Message msg) {
if(msg.what== Cart.ADD) {
//购物车添加 显示特效
if(cartAnimView== null) {
cartAnimView= (MyCartAnimView) findViewById(R.id.cart_anim);
}
cartAnimView.startAnim((View) msg.obj,mHd.imgCart, R.layout.view_move);
} else if(msg.what== Cart.MINU) {
//删除
}
updateCartUI();
}
@Override
protected voidonResume() {
super.onResume();
updateCartUI();
}
//查询购物车显示购物车状态
private voidupdateCartUI() {
//更新购买数量
intcount = Cart.getCart().findCountBySellerId(sSellerId);
mHd.tvSelectNum.setText(count + "");
mHd.tvSelectNum.setVisibility(count > 0 ? View.VISIBLE: View.INVISIBLE);
//更新总价
floattotalPrice = Cart.getCart().findPriceCountBySellerId(sSellerId);
mHd.tvCountPrice.setText(""+ CountPriceFormater.format(totalPrice));
mHd.tvSendPrice.setText("$"+ 30 +"起送");
mHd.tvDeliveryFee.setText("另需配置送费$"+ 5);
//如果总价大于配置总
mHd.tvSubmit.setVisibility(totalPrice > 30f ? View.VISIBLE: View.GONE);
mHd.tvSendPrice.setVisibility(totalPrice > 30f ? View.GONE: View.VISIBLE);
}
>3.如果没有问题就添加购物车特效
layout/activity_bussiness.xml
<com.itheima.app_.ui.MyCartAnimView
android:id="@+id/cart_anim"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="60dp"/>
l 调用如上红色代码
5.5. 添加购物车弹出视图编写显示逻辑
>1.布局UI
layout/cart_list.xml
<?xml version="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="#d7d4d4">
<ImageView
android:id="@+id/iv"
android:layout_width="5dp"
android:layout_height="20dp"
android:background="#227be1"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="15dp"
android:layout_toRightOf="@+id/iv"
android:text="购物车"/>
<TextView
android:id="@+id/tvClear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="15dp"
android:gravity="left|center_vertical"
android:drawableLeft="@drawable/icon_clean_up"
android:layout_alignParentRight="true"
android:drawablePadding="5dp"
android:layout_marginRight="20dp"
android:text="清空"/>
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_cart"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
layout/item_cart.xml
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="#FFFFFF"
android:gravity="center_vertical">
<TextView
android:id="@+id/tv_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="5dp"
android:layout_weight="1"
android:maxLines="1"
android:text="--商品"
android:textColor="#000"
android:textSize="12sp"/>
<TextView
android:id="@+id/tv_type_all_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginRight="10dp"
android:text="¥0"
android:textColor="#cd5656"
android:textSize="20sp"/>
<LinearLayout
android:id="@+id/ll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:orientation="horizontal">
<ImageButton
android:id="@+id/ib_minus"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="@drawable/button_minus"
android:visibility="visible"/>
<TextView
android:id="@+id/tv_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:text="0"
android:textColor="#000"
android:textSize="15sp"
android:visibility="visible"/>
<ImageButton
android:id="@+id/ib_add"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginRight="20dp"
android:background="@drawable/button_add"/>
</LinearLayout>
</LinearLayout>
>2.创建菜单控件的缓存holder(holder是使用集合的方式管理界面控件)
com.itheima.app_.ui.activity.BussinessActivity.CardListViewHolder
static classCardListViewHolder {
View sheetView;
@InjectView(R.id.iv)
ImageView iv;
@InjectView(R.id.tvClear)
TextView tvClear;
@InjectView(R.id.rv_cart)
RecyclerView rvCart;
publicCardListViewHolder(Context context) {
intlayoutId = R.layout.cart_list;
this.sheetView=View.inflate(context, layoutId,null);
ButterKnife.inject(this,sheetView);
}
public voidshowCartList()
{
//列表显示
rvCart.setLayoutManager(newLinearLayoutManager(rvCart.getContext()));
//添加适配器
CartItemAdapter adapter=newCartItemAdapter();
rvCart.setAdapter(adapter);
}
}
com.itheima.app_.ui.activity.BussinessActivity.BusinessViewHolder#onClick
@OnClick(R.id.bottom)
public voidonClick() {
//关联底部购物车列表
//如果购物车列表是显示的则隐藏
if(bottomSheetLayout!=null)
{
if(bottomSheetLayout.isSheetShowing()) {
bottomSheetLayout.dismissSheet();//隐藏
}else {
this.cartSheetHd.showCartList();
bottomSheetLayout.showWithSheetView(cartSheetHd.sheetView);//显示
}
}
}
>3.碰到rv关键就是适配器的创建(holder+adapter)
com.itheima.app_.ui.holder.CartItemViewHolder (代码都自动生成的)
com.itheima.app_.ui.adapter.CartItemAdapter
@Override
public voidonBindViewHolder(CartItemViewHolder holder,int position) {
final CartItem cartItem =mData.get(position);
holder.tvName.setText(cartItem.getGoodName());//显示价格
holder.tvCount.setText(cartItem.getCount()+"");//显示数量
floatprice=cartItem.getPriceSingle()*cartItem.getCount();//显示总价
holder.tvTypeAllPrice.setText(CountPriceFormater.format(price));
//添加点击事件
holder.ibAdd.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View v) {
Cart.getCart().update(cartItem.getGoodsId(),Cart.ADD);
mData=Cart.getCart().findCartItemsBySellerId(BussinessActivity.sSellerId);
notifyDataSetChanged();
//更新
Message msg=newMessage();
msg.what= Contants.CART_ITEM_ADD;
EventBus.getDefault().post(msg);
}
});
holder.ibMinus.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View v) {
Cart.getCart().update(cartItem.getGoodsId(),Cart.MINU);
mData=Cart.getCart().findCartItemsBySellerId(BussinessActivity.sSellerId);
notifyDataSetChanged();
Message msg=newMessage();
msg.what= Contants.CART_ITEM_MIN;
EventBus.getDefault().post(msg);
}
});
}
通知列表刷新即adapter.notifyDatasetChanged(还有要刷新的有底部列表与右侧商品列表)
要点:找到适配器进行刷新调用。
com.itheima.app_.ui.activity.BussinessActivity
@Subscribe(threadMode = ThreadMode.MAIN)
public voidonEvent(Message msg) {
if(msg.what== Cart.ADD) {
//购物车添加 显示特效
if(cartAnimView== null) {
cartAnimView= (MyCartAnimView) findViewById(R.id.cart_anim);
}
cartAnimView.startAnim((View) msg.obj,mHd.imgCart, R.layout.view_move);
updateCartUI();
} else if(msg.what== Cart.MINU) {
//删除
updateCartUI();
}else if( msg.what == Contants.CART_ITEM_ADD) {
updateCartUI();
}else if( msg.what== Contants.CART_ITEM_MIN) {
updateCartUI();
}
}
com.itheima.app_.ui.fragment.GoodFragment
@Subscribe(threadMode = ThreadMode.MAIN)
public voidonEvent(Message msg) {
//选择 typeId组的第一个元素
if(msg.what== Contants.CART_ITEM_ADD|| msg.what== Contants.CART_ITEM_MIN) {
mGoodStickListAdapter.notifyDataSetChanged();
}
}
l 引处可见eventBus的灵活性
5.6. 清空购物车逻辑
清空的思路
l 清空购物车里面所有的购物项CartItem
l 刷新当前购物车
l 刷新底部购物车状态
l 刷新右侧商品列表
只要一个消息即可,这也是eventBus的简洁
com.itheima.app_.ui.activity.BussinessActivity.CardListViewHolder
public voidshowCartList()
{
//列表显示
rvCart.setLayoutManager(newLinearLayoutManager(rvCart.getContext()));
//添加适配器
CartItemAdapter adapter=newCartItemAdapter();
rvCart.setAdapter(adapter);
tvClear.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View v) {
//清空弹出对话框提示
showDialog(v.getContext());
}
});
}
private voidshowDialog(Context context) {
newAlertDialog.Builder(context).setTitle("清空购物车")
.setPositiveButton("确认",new DialogInterface.OnClickListener() {
@Override
public voidonClick(DialogInterface dialog,int which) {
Cart.getCart().clearAll();
showCartList();//重新显示列表
Message msg=newMessage();
msg.what=Contants.CART_ITEM_ADD;
EventBus.getDefault().post(msg);
}
})//
.setNegativeButton("取消",null)//
.create()//
.show();;
}