HarmonyOS Codelab 优秀样例——购物应用,体验一次开发多端部署魅力
一. 样例介绍
本篇Codelab基于自适应布局和响应式布局,实现购物应用在手机、折叠屏、平板不同屏幕尺寸设备上按不同设计显示。通过三层工程结构组织代码,实现一次开发,多端部署 。
手机运行效果如图所示:
折叠屏运行效果图:
平板运行效果图:
相关概念
● 一次开发,多端部署:一套代码工程,一次开发上架,多端按需部署。支撑开发者快速高效的开发支持多种终端设备形态的应用。
● 自适应布局:当外部容器大小发生变化时,元素可以根据相对关系自动变化以适应外部容器变化的布局能力。相对关系如占比、固定宽高比、显示优先级等。当前自适应布局能力有7种:拉伸能力、均分能力、占比能力、缩放能力、延伸能力、隐藏能力、折行能力。自适应布局能力可以实现界面显示随外部容器大小连续变化。
● 响应式布局:当外部容器大小发生变化时,元素可以根据断点、栅格或特定的特征(如屏幕方向、窗口宽高等)自动变化以适应外部容器变化的布局能力。当前响应式布局能力有3种:断点、媒体查询、栅格布局。
● GridRow:栅格容器组件,仅可以和栅格子组件(GridCol)在栅格布局场景中使用。
● GridCol:栅格子组件,必须作为栅格容器组件(GridRow)的子组件使用。
完整示例:gitee源码地址
二. 环境搭建
我们首先需要完成HarmonyOS开发环境搭建,可参照如下步骤进行。
软件要求
● DevEco Studio版本:DevEco Studio 3.1 Release及以上版本。
● HarmonyOS SDK版本:API version 9及以上版本。
硬件要求
● 设备类型:华为手机或运行在DevEco Studio上的华为手机设备模拟器。
● HarmonyOS系统:3.1.0 Developer Release及以上版本。
环境搭建
1. 安装DevEco Studio,详情请参考下载和安装软件。
2. 设置DevEco Studio开发环境,DevEco Studio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境:
● 如果可以直接访问Internet,只需进行下载HarmonyOS SDK操作。
● 如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境。
1. 开发者可以参考以下链接,完成设备调试的相关配置:
● 使用真机进行调试
三.代码结构解读
本篇Codelab只对核心代码进行讲解,common为公共能力层,feature为功能模块层,本示例分为六个模块,product则为产品层。对于完整代码,我们会在源码下载或gitee中提供。
├──common/src/main/ets // 公共能力层
│ ├──bean
│ │ ├──CommodityModel.ets // 商品数据实体类
│ │ ├──OrderModel.ets // 订单数据实体类
│ │ └──ProductModel.ets // 购物车商品数据实体类
│ ├──components
│ │ ├──CommodityList.ets // 商品列表组件
│ │ ├──CounterProduct.ets // 数量加减组件
│ │ └──EmptyComponent.ets // 无数据显示组件
│ ├──constants
│ │ ├──BreakpointConstants.ets // 断点常量类
│ │ ├──GridConstants.ets // 栅格常量类
│ │ └──StyleConstants.ets // 样式常量类
│ ├──utils
│ │ ├──BreakpointSystem.ets // 断点工具类
│ │ ├──CommonDataSource.ets // 数据封装类
│ │ ├──LocalDataManager.ets // 数据操作管理类
│ │ ├──Logger.ets.ets // 日志工具类
│ │ └──Utils.ets // 方法工具类
│ └──viewmodel
│ └──ShopData.ets // 商品应用数据
├──features // 功能模块层
│ ├──commoditydetail/src/main/ets // 商品详情内容区
│ │ ├──bean
│ │ │ └──TypeModel.ets // 实体类
│ │ ├──components
│ │ │ ├──CapsuleGroupButton.ets // 自定义按钮组件
│ │ │ ├──CommodityDetail.ets // 商品详情组件
│ │ │ └──SpecificationDialog.ets // 商品规格弹框
│ │ ├──constants
│ │ │ └──CommodityConstants.ets // 商品详情区常量类
│ │ └──viewmodel
│ │ └──CommodityDetailData.ets // 商品详情数据类
│ ├──home/src/main/ets // 首页内容区
│ │ ├──components
│ │ │ └──Home.ets // 首页内容组件
│ │ └──viewmodel
│ │ └──HomeData.ets // 首页数据
│ ├──newproduct/src/main/ets // 新品内容区
│ │ ├──components
│ │ │ └──NewProduct.ets // 新品内容组件
│ │ └──viewmodel
│ │ └──NewProductData.ets // 新品数据
│ ├──orderdetail/src/main/ets // 订单相关内容区
│ │ ├──components
│ │ │ ├──AddressInfo.ets // 收件人信息组件
│ │ │ ├──CommodityOrderItem.ets // 商品订单信息组件
│ │ │ ├──CommodityOrderList.ets // 商品订单列表组件
│ │ │ ├──ConfirmOrder.ets // 确认订单组件
│ │ │ ├──HeaderBar.ets // 标题组件
│ │ │ ├──OrderDetailList.ets // 订单分类列表组件
│ │ │ ├──OrderListContent.ets // 订单分类列表内容组件
│ │ │ └──PayOrder.ets // 支付订单组件
│ │ ├──constants
│ │ │ └──OrderDetailConstants.ets // 订单区常量类
│ │ └──viewmodel
│ │ └──OrderData.ets // 订单数据
│ ├──personal/src/main/ets // 我的内容区
│ │ ├──bean
│ │ │ └──IconButtonModel.ets // 按钮图标实体类
│ │ ├──components
│ │ │ ├──IconButton.ets // 图片按钮组件
│ │ │ ├──LiveList.ets // 直播列表组件
│ │ │ └──Personal.ets // 我的内容组件
│ │ ├──constants
│ │ │ └──PersonalConstants.ets // 我的常量类
│ │ └──viewmodel
│ │ └──PersonalData.ets // 我的数据
│ └──shopcart/src/main/ets // 购物车内容区
│ ├──components
│ │ └──ShopCart.ets // 购物车内容组件
│ └──constants
│ └──ShopCartConstants.ets // 购物车常量类
└──products // 产品层
└──phone/src/main/ets // 支持手机、平板
├──constants
│ └──PageConstants.ets // 页面常量类
├──entryability
│ └──EntryAbility.ets // 程序入口类
├──pages
│ ├──CommodityDetailPage.ets // 订单详情页
│ ├──ConfirmOrderPage.ets // 确认订单页
│ ├──MainPage.ets // 主页
│ ├──OrderDetailListPage.ets // 订单分类列表页
│ ├──PayOrderPage.ets // 支付订单页
│ └──SplashPage.ets // 启动过渡页
└──viewmodel
└──MainPageData.ets // 主页数据
四. 应用主框架
4.1 启动页
在工程pages目录中,选中Index.ets,点击鼠标右键 > Refactor > Rename,改名为SplashPage.ets。改名后,修改工程entryability目录下EntryAbility.ets文件中windowStage.loadContent方法第一个参数为pages/SplashPage。在该页面的周期函数aboutToAppear里添加一个2秒的定时任务跳转到主页实现。
// EntryAbility.ets
windowStage.loadContent('pages/SplashPage', (err, data) => {
if (err.code) {
...
}
}); // SplashPage.ets
build() {
Column() {
...
}
.height(StyleConstants.FULL_HEIGHT)
.width(StyleConstants.FULL_WIDTH)
.backgroundColor($r('app.color.page_background'))
} aboutToAppear() {
this.breakpointSystem.register();
this.timeOutId = setTimeout(() => {
router.replaceUrl({ url: PageConstants.MAIN_PAGE_URL })
.catch(err => {
Logger.error(JSON.stringify(err));
})
}, PageConstants.DELAY_TIME);
} aboutToDisappear() {
this.breakpointSystem.unregister();
clearTimeout(this.timeOutId);
}
手机运行效果图:
折叠屏运行效果图:
平板运行效果图:
4.2 主页
本篇Codelab主页由Tabs容器组件和四个TabContent子组件组成,四个TabContent页签的内容视图分别为首页(Home)、新品(NewProduct)、购物车(ShopCart)、我的(Personal)。根据用户使用场景,通过响应式布局的媒体查询,监听应用窗口宽度变化,获取当前应用所处的断点值,设置Tabs的页签位置,lg断点如平板则显示侧边栏,其他断点的则显示底部栏。
/// MainPage.ets
build() {
Column() {
Tabs({
barPosition: this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG ?
BarPosition.Start : BarPosition.End,
index: this.currentPageIndex
}) {
...
.barWidth(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG ?
$r('app.float.bar_width') : StyleConstants.FULL_WIDTH)
.barHeight(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG ?
StyleConstants.SIXTY_HEIGHT : $r('app.float.vp_fifty_six'))
.vertical(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG)
}
.backgroundColor($r('app.color.page_background'))
}
主页页面展示:
五. 页面介绍
5.1 首页标签页
首页标签页通过自适应布局的均分、拉伸等能力实现搜索框、分类等布局,通过响应式布局的媒体查询、断点能力设置轮播图数、商品列表数。
通过响应式布局的媒体查询,监听应用窗口宽度变化,获取当前应用所处的断点值,设置商品列表列数和轮播图数,lg断点显示4列3张轮播图,md断点显示3列2张轮播图,sm断点显示2列1张轮播图。
// Home.ets
@Builder CustomSwiper() {
Swiper() {
ForEach(swiperImage, (item: Resource) => {
Image(item)
.width(StyleConstants.FULL_WIDTH)
.aspectRatio(StyleConstants.IMAGE_ASPECT_RATIO)
}, item => JSON.stringify(item))
}
.itemSpace(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_SM ? 0 :
StyleConstants.ITEM_SPACE)
.indicator(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_SM)
.displayCount(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG ?
StyleConstants.DISPLAY_THREE :
(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_MD ? StyleConstants.DISPLAY_TWO :
StyleConstants.DISPLAY_ONE))
} // Home.ets
CommodityList({
commodityList: $commodityList,
column: this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG ? StyleConstants.DISPLAY_FOUR :
(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_MD ?
StyleConstants.DISPLAY_THREE : StyleConstants.DISPLAY_TWO),
onClickItem: (data: Commodity) => this.onClickItem(data)
}) // CommodityList.ets
build() {
if (this.commodityList.length > 0) {
List({ space: StyleConstants.TWELVE_SPACE }) {
LazyForEach(new CommonDataSource(this.commodityList), (item: Commodity) => {
...
}, item => JSON.stringify(item))
}
...
.lanes(this.column)
} else {
EmptyComponent({ outerHeight: StyleConstants.FIFTY_HEIGHT })
}
}
使用自适应布局的均分能力,在Flex布局中设置主轴上的对齐方式为FlexAlign.SpaceAround,使循环渲染的组件之间距离相同,第一个元素到行首的距离和最后一个元素到行尾的距离是相邻元素之间距离的一半。
// Home.ets
@Builder ActivityTitle() {
Flex({ justifyContent: FlexAlign.SpaceAround }) {
ForEach(activityTitle, (item: ActivityTitleModel, index: number) => {
Flex({
direction: FlexDirection.Column,
justifyContent: FlexAlign.Center,
alignItems: ItemAlign.Center
}) {
...
}
}, item => JSON.stringify(item))
}
...
}
手机运行效果图:
折叠屏运行效果图
平板运行效果图
5.2 新品标签页
新品标签页由轮播图、分类、新品列表组成,通过响应式布局的媒体查询、断点能力和自适应布局的均分能力,实现不同设备类型显示不同效果,实现逻辑同主页。
通过响应式布局的媒体查询,监听应用窗口宽度变化,获取当前应用所处的断点值设置新品列表,sm断点显示2列,md、lg断点显示3列。
// NewProduct.ets
@Builder ProductList() {
List({ space: StyleConstants.TWELVE_SPACE }) {
LazyForEach(new CommonDataSource(productData), (item: ProductDataModel) => {
ListItem() {
...
}, item => JSON.stringify(item))
}
.lanes(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_SM ?
StyleConstants.DISPLAY_TWO : StyleConstants.DISPLAY_THREE)
.padding({ left: $r('app.float.vp_twelve'), right: $r('app.float.vp_twelve') })
}
手机运行效果图:
折叠屏运行效果图
平板运行效果图
5.3 购物车标签页
购物车标签页,由购物车列表和商品列表组成,商品列表实现逻辑同主页的商品列表,购物车列表使用自适应布局的均分能力实现。
// ShopCart.ets
@Builder CartItem(item: Product, index: number) {
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {
...
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.SpaceAround }) {
Text($r('app.string.commodity_piece_description', item.name, item.description))
...
Text(`${Object.values(item.specifications).join(',')}`)
...
Flex({ justifyContent: FlexAlign.SpaceBetween }) {
Text() {
...
} CounterProduct({
count: item.count,
onNumberChange: (num: number) => {
this.onChangeCount(num, item);
}
})
}
}
...
}
}
手机运行效果图:
折叠屏运行效果图
平板运行效果图
5.4 我的标签页
我的标签页主要由个人信息、我的订单、文字图片按钮、直播列表组成,直播列表实现方案同主页商品列表,其他则使用自适应布局的均分能力,Flex布局设置主轴上的对齐方式为FlexAlign.SpaceAround。
// Personal.ets
@Builder Order() {
Flex({direction: FlexDirection.Column}) {
Flex({
justifyContent: FlexAlign.SpaceBetween,
alignItems: ItemAlign.Center
}) {
Text($r('app.string.order_mine'))
.fontSize($r('app.float.middle_font_size'))
Row() {
...
}
...
})
}
Flex({
justifyContent: FlexAlign.SpaceAround,
alignItems: ItemAlign.Center
}) {
ForEach(this.orderIconButton, (iconButton: IconButtonModel) => {
IconButton({
props: iconButton,
click: this.onOrderButtonClick.bind(this, iconButton.key)
})
}, (iconButton) => JSON.stringify(iconButton))
}
.width(StyleConstants.FULL_WIDTH)
} @Builder IconDock(buttons: IconButtonModel[]) {
Flex({
justifyContent: FlexAlign.SpaceAround,
alignItems: ItemAlign.Center
}) {
ForEach(buttons, (iconButton: IconButtonModel) => {
IconButton({
props: iconButton
})
}, (iconButton) => JSON.stringify(iconButton))
}
.height($r('app.float.icon_dock_height'))
.padding($r('app.float.vp_twelve'))
.cardStyle()
}
手机运行效果图:
折叠屏运行效果图:
平板运行效果图:
5.5 商品详情页
商品详情页整体由轮播图、商品信息、底部按钮栏组成,通过响应式布局能力的栅格布局,实现不同设备类型显示不同的效果,并通过自适应布局的拉伸能力,设置flexGrow属性使按钮位于底部。
● 在sm断点下,轮播图占4个栅格,商品信息占4个栅格,底部按钮栏占4个栅格。
● 在md断点下,轮播图占8个栅格,商品信息占8个栅格,底部按钮栏占8个栅格。
● 在lg断点下,轮播图占12个栅格,商品信息占8个栅格偏移2个栅格,底部按钮栏占8个栅格偏移2个栅格。
// CommodityDetail.ets
build() {
Stack({ alignContent: Alignment.TopStart }) {
Flex({ direction: FlexDirection.Column }) {
Scroll() {
GridRow({
columns: {
sm: GridConstants.COLUMN_FOUR,
md: GridConstants.COLUMN_EIGHT,
lg: GridConstants.COLUMN_TWELVE
},
gutter: GridConstants.GUTTER_TWELVE
}) {
GridCol({
span: {
sm: GridConstants.SPAN_FOUR,
md: GridConstants.SPAN_EIGHT,
lg: GridConstants.SPAN_TWELVE }
}) {
this.CustomSwiper(this.info.images)
}
GridCol({
span: {
sm: GridConstants.SPAN_FOUR,
md: GridConstants.SPAN_EIGHT,
lg: GridConstants.SPAN_EIGHT
},
offset: { lg: GridConstants.OFFSET_TWO }
}) {
Column() {
...
}
}
}
}
.flexGrow(StyleConstants.FLEX_GROW)
GridRow({
columns: {
sm: GridConstants.COLUMN_FOUR,
md: GridConstants.COLUMN_EIGHT,
lg: GridConstants.COLUMN_TWELVE
},
gutter: GridConstants.GUTTER_TWELVE
}) {
GridCol({
span: {
sm: GridConstants.SPAN_FOUR,
md: GridConstants.SPAN_EIGHT,
lg: GridConstants.SPAN_EIGHT
},
offset: { lg: GridConstants.OFFSET_TWO } }) {
this.BottomMenu()
}
}
}
...
}
}
手机运行效果图:
折叠屏运行效果图:
平板运行效果图:
5.6 订单确认页
订单确认页由上方收件信息、订单信息、底部的总价和提交订单按钮组成,通过响应式布局的栅格布局,实现不同设备类型显示不同的效果,并通过自适应布局的拉伸能力,设置flexGrow属性使总价和提交订单按钮位于底部。
● 在sm断点下,上方收件信息和订单信息占4个栅格,底部总价占2个栅格,底部提交订单按钮占2个栅格。
● 在md断点下,上方收件信息和订单信息占8个栅格,底部总价占2个栅格,底部按钮占3个栅格偏移3个栅格。
● 在lg断点下,上方收件信息和订单信息占8个栅格偏移2个栅格,底部总价占2个栅格偏移2个栅格,底部按钮占3个栅格偏移3个栅格。
// ConfirmOrder.ets
build() {
Flex({ direction: FlexDirection.Column }) {
HeaderBar({
...
})
Column(){
Scroll() {
GridRow({
columns: {
sm: GridConstants.COLUMN_FOUR,
md: GridConstants.COLUMN_EIGHT,
lg: GridConstants.COLUMN_TWELVE
}
}) {
GridCol({
span: {
sm: GridConstants.SPAN_FOUR,
md: GridConstants.SPAN_EIGHT,
lg: GridConstants.SPAN_EIGHT
},
offset: { lg: GridConstants.OFFSET_TWO }
}) {
Column() {
AddressInfo()
CommodityOrderList()
}
}
}
}
.scrollBar(BarState.Off)
}
.flexGrow(StyleConstants.FLEX_GROW)
.padding({ left: $r('app.float.vp_twelve'), right: $r('app.float.vp_twelve') })
GridRow({
columns: {
sm: GridConstants.COLUMN_FOUR,
md: GridConstants.COLUMN_EIGHT,
lg: GridConstants.COLUMN_TWELVE
},
gutter: GridConstants.GUTTER_TWELVE
}) {
GridCol({
span: {
sm: GridConstants.SPAN_TWO,
md: GridConstants.SPAN_TWO,
lg: GridConstants.SPAN_TWO
},
offset: { lg: GridConstants.OFFSET_TWO }
}) {
Text($r('app.string.bottom_bar_amount', this.amount))
...
}
GridCol({
span: {
sm: GridConstants.SPAN_TWO,
md: GridConstants.SPAN_THREE,
lg: GridConstants.SPAN_THREE
},
offset: {
md: GridConstants.OFFSET_THREE,
lg: GridConstants.OFFSET_THREE
}
}) {
Button($r('app.string.bottom_bar_button'))
...
}
}
...
}
...
}
手机运行效果图:
折叠屏运行效果图:
平板运行效果图:
5.7 订单支付页
订单支付页整体由上方订单信息和底部的去支付按钮组成,通过使用响应式布局的栅格布局实现不同设备类型显示不同效果,并通过自适应布局的拉伸能力,设置flexGrow属性使去支付按钮位于底部。
● 在sm断点下,上方订单信息占4个栅格,底部去支付按钮占2个栅格偏移2个栅格。
● 在md断点下,上方订单信息占8个栅格,底部去支付按钮占2个栅格偏移6个栅格。
● 在lg断点下,上方订单信息占8个栅格偏移2个栅格,底部去支付按钮占2个栅格偏移8个栅格。
// PayOrder.ets
build() {
Flex({ direction: FlexDirection.Column }) {
HeaderBar({
...
})
Stack({ alignContent: Alignment.TopStart }) {
...
Column() {
Scroll() {
GridRow({
columns: {
sm: GridConstants.COLUMN_FOUR,
md: GridConstants.COLUMN_EIGHT,
lg: GridConstants.COLUMN_TWELVE
}
}) {
GridCol({
span: {
sm: GridConstants.SPAN_FOUR,
md: GridConstants.SPAN_EIGHT,
lg: GridConstants.SPAN_EIGHT
},
offset: { lg: GridConstants.OFFSET_TWO }
}) {
Column() {
this.OrderStatus()
...
}
}
}
}
.scrollBar(BarState.Off)
}
.padding({ left: $r('app.float.vp_twelve'), right: $r('app.float.vp_twelve') })
}
.flexGrow(StyleConstants.FLEX_GROW) GridRow({
columns: {
sm: GridConstants.COLUMN_FOUR,
md: GridConstants.COLUMN_EIGHT,
lg: GridConstants.COLUMN_TWELVE
}
}) {
GridCol({
span: {
sm: GridConstants.SPAN_TWO,
md: GridConstants.SPAN_TWO,
lg: GridConstants.SPAN_TWO
},
offset: {
sm: GridConstants.OFFSET_TWO,
md: GridConstants.OFFSET_SIX,
lg: GridConstants.OFFSET_EIGHT
}
}) {
this.BottomBar()
}
}
}
...
}
手机运行效果图:
折叠屏运行效果图:
平板运行效果图:
5.8 订单列表页
订单列表页整体布局通过响应式布局的栅格布局,实现不同设备类型显示不同的效果。
● 在sm断点下,整体UX占4个栅格。
● 在md断点下,整体UX占8个栅格。
● 在lg断点下,整体UX占8个栅格偏移2个栅格。
// OrderListContent.ets
build() {
Column() {
Scroll() {
GridRow({
columns: {
sm: GridConstants.COLUMN_FOUR,
md: GridConstants.COLUMN_EIGHT,
lg: GridConstants.COLUMN_TWELVE
}
}) {
GridCol({
span: {
sm: GridConstants.SPAN_FOUR,
md: GridConstants.SPAN_EIGHT,
lg: GridConstants.SPAN_EIGHT
},
offset: { lg: GridConstants.OFFSET_TWO }
}) {
Column() {
...
}
}
}
}
.scrollBar(BarState.Off)
}
...
}
手机运行效果图:
折叠屏运行效果图:
平板运行效果图:
六. 总结
您已经完成了本次Codelab的学习,并了解到以下知识点:
1. 针对不同屏幕尺寸的设备完成一次开发,多端部署页面设计。
2. 按照三层工程结构划分模块、组织代码。
3. 通过自适应布局、响应式布局、栅格布局实现一次开发,多端部署。
HarmonyOS Codelab 优秀样例——购物应用,体验一次开发多端部署魅力的更多相关文章
- Cocos2d-x 3.2Lua演示样例UserDefaultTest(用户默认配置)
Cocos2d-x 3.2演示样例UserDefaultTest(用户默认配置) 本篇博客介绍Cocos2d-x 3.2演示样例中的UserDefaulstTest,我们在开发中可能须要用到一些默认配 ...
- [b0007] windows 下 eclipse 开发 hdfs程序样例
目的: 学习使用hdfs 的java命令操作 相关: 进化: [b0010] windows 下 eclipse 开发 hdfs程序样例 (二) [b0011] windows 下 eclipse 开 ...
- 33个超级有用必须要收藏的PHP代码样例
作为一个正常的程序员,会好几种语言是十分正常的,相信大部分程序员也都会编写几句PHP程序,如果是WEB程序员,PHP一定是必备的,即使你没用开发过大型软件项目,也一定多少了解它的语法. 在PHP的流行 ...
- Swift - 自动布局库SnapKit的使用详解1(配置、使用方法、样例)
为了适应各种屏幕尺寸,iOS 6后引入了自动布局(Auto Layout)的概念,通过使用各种 Constraint(约束)来实现页面自适应弹性布局. 在 StoryBoard 中使用约束实现自动布局 ...
- 百度地图 Android SDK - 检索功能使用的简单演示样例
百度地图 SDK 不仅为广大开发人员提供了炫酷的地图展示效果.丰富的覆盖物图层,更为广大开发人员提供了多种 LBS 检索的能力. 通过这些接口,开发人员能够轻松的訪问百度的 LBS 数据,丰富自己的移 ...
- Ajax框架,DWR介绍,应用,样例
使用Ajax框架 1. 简化JavaScript的开发难度 2. 解决浏览器的兼容性问题 3. 简化开发流程 经常使用Ajax框架 Prototype 一个纯粹的JavaScript函数库,对Ajax ...
- MapGuide应用程序演示样例——你好,MapGuide!
图 3‑4显示了基于MapGuide的Web应用程序的开发流程,整个开发流程能够分为五个阶段.图中,矩形代表任务,椭圆形被任务使用的或被任务创建的实体,箭头代表数据流. 1) 载入文件类型的数据,配置 ...
- Macaca环境配置及样例执行
1.Macaca简介 macaca是由阿里巴巴公司开发的一套自动化解决方案,适用于PC端和移动端.Macaca基于Node.js开发,测试案例编写语言暂时也只支持Node.js. 2.Macaca与A ...
- redis cmd 使用样例
Redis 命令參考 一 Redis介绍 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15 ...
- 源代码方式向openssl中加入新算法完整具体步骤(演示样例:摘要算法SM3)【非engine方式】
openssl简单介绍 openssl是一个功能丰富且自包括的开源安全工具箱.它提供的主要功能有:SSL协议实现(包括SSLv2.SSLv3和TLSv1).大量软算法(对称/非对称/摘要).大数运算. ...
随机推荐
- 【Azure 应用服务】App Service for Windows 环境中为Tomcat自定义4xx/5xx页面
问题描述 通过设置Java Web项目,实现在App Service For Windows环境中达到自定义4XX/5XX的页面效果 问题解答 第一步:在本地项目文件中打开web.xml文件 (src ...
- .Net缓存之MemoryCahe
1. MemoryCahe NetCore中的缓存和System.Runtime.Caching很相似,但是在功能上做了增强,缓存的key支持object类型:提供了泛型支持:可以读缓存和单个缓存项的 ...
- 计算机网络-IP地址
目录 子网划分 定长子网划分 子网划分的方法 子网掩码 可变长子网划分 无类别编址 网络前缀 路由聚合 特殊用途的IP地址 专用网络地址 链路本地地址 运营商级NAT共享地址 用于文档的测试网络地址 ...
- PhpStorm设置FTP功能
1.版本介绍 本文操作针对PhpStorm 2020.1版本 2.[ctrl + alt + s]打开设置,选择"Build,Execution,Deployment" 3.选择& ...
- Codeforces Round #848 (Div. 2) A~F 题解
A. Flip Flop Sum 能换 \(-1,-1\) 就换,不能能换 \(1,-1\) 或 \(-1,1\) 也可以,否则只能换 \(1,1\). B. The Forbidden Permut ...
- (转载)Transfer-Encoding:chunked详解
原文链接:Transfer-Encoding:chunked详解_transfer-encoding: chunked_公众号:流花鬼的博客-CSDN博客 概念 分块传输编码(Chunked tran ...
- Servlet中访问路径配置为/*时,使用请求转发造成内存溢出
一.问题由来 最近在测试Servlet的请求转发功能,准备抽取一个公共的PageJumpTestServlet,用来做页面跳转功能. 这样不用每次在测试的时候,都单独写一个Servlet用来做页面跳转 ...
- 摆脱鼠标系列 - 百度搜索 - 火柴 - 快捷键 Ctrl两次
摆脱鼠标系列 - 百度搜索 - 火柴 - 快捷键 Ctrl两次 有两款软件 utools 和 火柴,试用后觉得火柴符合试用功能 这里只用网络搜索 其他功能均不用 搜索用双核浏览器 因为用的老的chro ...
- git 提交本地仓库 提交错误撤销命令
git reset --hard HEAD~1
- python parser 实例解析
一 parser: 该模块为Python的内部解析器和字节码编译器提供了一个接口.该接口的主要目的是允许Python代码编辑Python表达式的分析树并从中创建可执行代码. 这比试图将任意Python ...