首先我们来看一下最终的实现效果【添加不同的咖啡后,自动更新价格和数量,并且添加到首页底部的已点菜单栏中】
加入购物车
后,首页对应的咖啡右边的数量进行更新,并且底部菜单栏中的总数量进行更新template_ordered.xml
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="110vp"
ohos:width="match_parent"
ohos:orientation="horizontal">
<Image
ohos:left_margin="15vp"
ohos:layout_alignment="vertical_center"
ohos:height="20vp"
ohos:width="20vp"
ohos:image_src="$media:choose"
ohos:scale_mode="zoom_center"
ohos:clip_alignment="center"/>
<Image
ohos:left_margin="20vp"
ohos:id="$+id:coffee_img"
ohos:height="90vp"
ohos:width="90vp"
ohos:image_src="$media:coffee1"
ohos:scale_mode="stretch"
ohos:clip_alignment="center"
ohos:layout_alignment="center"/>
<DirectionalLayout
ohos:left_margin="14vp"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:orientation="vertical">
<Text
ohos:top_margin="5vp"
ohos:id="$+id:coffee_title"
ohos:height="match_content"
ohos:width="match_content"
ohos:text="厚乳拿铁"
ohos:text_color="#313131"
ohos:text_size="20fp"
ohos:text_alignment="center"/>
<Text
ohos:id="$+id:coffee_taste"
ohos:height="match_content"
ohos:width="match_content"
ohos:text="热/不另外加糖"
ohos:text_color="#313131"
ohos:text_size="12fp"
ohos:text_alignment="center"/>
<DirectionalLayout
ohos:height="26vp"
ohos:width="match_parent"
ohos:top_margin="28vp"
ohos:orientation="horizontal">
<Text
ohos:id="$+id:coffee_price"
ohos:height="match_content"
ohos:width="match_content"
ohos:text="¥16"
ohos:text_color="#dd5810"
ohos:text_size="18fp"
ohos:text_alignment="center"/>
<DirectionalLayout
ohos:height="match_parent"
ohos:width="match_parent"
ohos:alignment="right"
ohos:orientation="horizontal">
<Image
ohos:height="32vp"
ohos:width="32vp"
ohos:image_src="$media:minus"
ohos:layout_alignment="vertical_center"
ohos:padding="5vp"
ohos:scale_mode="stretch"/>
<Text
ohos:id="$+id:coffee_num"
ohos:height="match_content"
ohos:width="match_content"
ohos:left_margin="2vp"
ohos:right_margin="2vp"
ohos:text="1"
ohos:text_alignment="vertical_center"
ohos:text_size="20fp"/>
<Image
ohos:height="32vp"
ohos:width="32vp"
ohos:image_src="$media:plus"
ohos:layout_alignment="vertical_center"
ohos:padding="5vp"
ohos:scale_mode="stretch"/>
DirectionalLayout>
DirectionalLayout>
DirectionalLayout>
DirectionalLayout>
当我们在详情页点击
添加购物车
后,需要将已点咖啡添加到菜单栏中,其实这里的逻辑还是比较复杂的,主要是要对PageSlice的生命周期有一定的基础,不然无从下手,大家可以先思考一下,你拿到回调的信息后如何渲染到已点咖啡的模板中!
可能你会想为什么不能在回调方法onResult中渲染模板,你可以尝试一下,是不行的,因为这里我们无法获取模板中的组件【比如说通过findComponentById获得组件】,只能对模板中的信息进行修改更新。所以我们另辟蹊径,通过pageSlice的生命周期渲染模板
【如图所示:我们如何渲染模板呢?】
我们知道:
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
// 更新每一个咖啡后面紧跟的咖啡数量
DirectionalLayout curCoffee = everyCoffee.get(curClickCoffee);
Text textNum = (Text) curCoffee.findComponentById(ResourceTable.Id_num);
int num = Integer.parseInt(textNum.getText()) + totalNum;
textNum.setText(num + "");
// 更新总数量
int curTotalNum = Integer.parseInt(txt_totalNum.getText());
txt_totalNum.setText(curTotalNum + totalNum + "");
// 更新当前总价
countCartPrice(totalNum * price,true);
// 加载已点咖啡到核算栏
if (!isCoffeeExist.contains(title)){
initCoffeeOrder();
isCoffeeExist.add(title);
}else{
updateCoffeeOrder(true);
}
}
// 计算已点菜单价格
private void countCartPrice(int price, boolean isadd) {
int total = Integer.parseInt(txt_price.getText().substring(1));
if (isadd) {
total = total + price;
} else {
total = total - price;
}
txt_price.setText("¥"+total);
}
private void initCoffeeOrder(){
DirectionalLayout tempOrder = (DirectionalLayout) LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_template_ordered, null, false);
Text tempTitle = (Text) tempOrder.findComponentById(ResourceTable.Id_coffee_title);
Text tempPrice = (Text) tempOrder.findComponentById(ResourceTable.Id_coffee_price);
Text tempTaste = (Text) tempOrder.findComponentById(ResourceTable.Id_coffee_taste);
Text tempNum = (Text) tempOrder.findComponentById(ResourceTable.Id_coffee_num);
getUITaskDispatcher().asyncDispatch(() -> {
tempTitle.setText(title);
tempPrice.setText("¥"+price);
tempTaste.setText(temperature+"/"+sweet);
tempNum.setText(totalNum + "");
coffeeOrdered.addComponent(tempOrder);
});
tempOrderCoffee.put(curClickCoffee, tempOrder);
}
/**
* 更新 底部的已点咖啡
* @param isAdd:判断是否点击的是添加按钮
*/
private void updateCoffeeOrder(boolean isAdd){
DirectionalLayout curClickOrderCoffee = tempOrderCoffee.get(curClickCoffee);
Text tempNum = (Text) curClickOrderCoffee.findComponentById(ResourceTable.Id_coffee_num);
int num = Integer.parseInt(tempNum.getText());
if (isAdd){
tempNum.setText(num + totalNum + "");
} else {
tempNum.setText(num - 1 + "");
}
}
我们观察一下,做了哪些事:
HashSet
作为容器,用咖啡的名称作为判断的哈希依据我是使用了一个List作为容器,直接获取当前列表中的点击的第
curClickCoffee
个咖啡模板
包括,底部的菜单中的已点咖啡我们也用一个HashMap容器进行包裹
我们再重新回过头来看,这不是一切都清晰明了了!当我们需要更新模板中的信息时,只要根据 curClickCoffee 获取当前点击的模板,然后对其中表示数量的文本组进行数量更新
我们平时使用APP时,可以点击核算栏【菜单栏】后会展示详细我们已点的咖啡,就是2.1节我们渲染的模板,再次点击后会隐藏
// 显示所有的已点咖啡
private void showCartCoffee(){
Component cartDL = findComponentById(ResourceTable.Id_cart_dl);
Component coffeeOrder = findComponentById(ResourceTable.Id_coffee_order);
Component discount =findComponentById(ResourceTable.Id_discount_txt);
cartDL.setClickedListener(component -> {
if (!isShowCoffeeMenu){
discount.setVisibility(Component.HIDE);
coffeeOrder.setVisibility(Component.VISIBLE);
cartDL.setMarginTop(vp2px(28));
isShowCoffeeMenu = !isShowCoffeeMenu;
}else {
discount.setVisibility(Component.VISIBLE);
coffeeOrder.setVisibility(Component.HIDE);
isShowCoffeeMenu = !isShowCoffeeMenu;
cartDL.setMarginTop(0);
}
});
}
这里又有细节哦,我们点击显示已点开发后,中间的优惠信息会被隐藏,这时候需要我们cartDL.setMarginTop(vp2px(28))
设置一个边距,不然下面的信息会跑上去【因为文本被隐藏了】,再次点击后我们重新显示优惠信息,将已点咖啡隐藏……中间的一切通过一个boolean变量控制是否显示已点咖啡
我们回想喝多种品类的咖啡,因此我们点击首页不同的咖啡 右边对应的+
按钮时,会发现上一次点击的咖啡温度和糖度,以及数量会被保存下来!这是一个小Bug,当时我思考了很久为什么?我们可以看一下这个Bug!!
添加第二类咖啡的时候,温度、糖度和数量都没被重置!
这里因为回调的时候虽然使用了terminate销毁了当前界面,但是我们使用setText设置的文本信息已经被保存在了xml文件中,换句话说我们xml文件中的文本已经变成了你点击后的值,并不会在下一次重新点击后重新换回来,我们重新加载slice,只是加载了xml文件;【但是你的xml文件已经被改动过了对吧!】
考虑到用户可能会喜欢统一的温度和糖度,所以这两个不更改,只对已点数量进行修改【因为调用terminate会自动调用onStop销毁页面,所以我们直接通过生命周期的onStop方法在每一次销毁前,将已点数量恢复到 1
即可】