HarmonyOS 鸿蒙Next中子组件没有按照起始端对齐
HarmonyOS 鸿蒙Next中子组件没有按照起始端对齐
import router from '[@ohos](/user/ohos).router'
import { promptAction, UIContext } from '[@kit](/user/kit).ArkUI';
import { UserRepository } from '../util/UserRepository';
import {
TyResult,
SysDictData,
SysDictDataResult,
PaginationParams,
PaginationResult,
InspectionLog,
InspectionQuestion,
Inspectionlogsoid
} from '../util/dbutil';
import common from '[@ohos](/user/ohos).app.ability.common';
// 问题数据结构接口
interface ProblemItem {
question: string;
ft: string;
}
// Select选项接口
interface SelectOption {
value: string;
icon?: Resource;
}
// 搜索表单类
class SearchForm {
id: string = '';
area: string = '';
date: string = '';
status: number | undefined = undefined;
}
[@Entry](/user/Entry)
[@Component](/user/Component)
struct MainPage {
private uiContext = new UIContext();
// 状态管理
[@State](/user/State) currentMenu: string = 'check-record'
[@State](/user/State) dataList: boolean = true
[@State](/user/State) formPd: string = ''
[@State](/user/State) isLoading: boolean = false
[@State](/user/State) isDatabaseReady: boolean = false
// 数据管理
[@State](/user/State) sysDictdata: SysDictData[] = []
[@State](/user/State) inspectionLog: InspectionLog[] = []
[@State](/user/State) searchForm: SearchForm = new SearchForm()
[@State](/user/State) bh: string = ''
// 分页管理
[@State](/user/State) currentPage: number = 1
[@State](/user/State) pageSize: number = 10
[@State](/user/State) totalPages: number = 0
[@State](/user/State) totalRecords: number = 0
// 表返回消息 PaginationResult中的data 可能是任何对象
[@State](/user/State) inspectionlogsResult: PaginationResult<InspectionLog> = {
success: false,
data: undefined,
message: '',
total: 0,
page: 0,
pageSize: 0,
totalPages: 0
}
//码表返回消息
[@State](/user/State) sysDictDataResult: SysDictDataResult = {
success: false,
data: undefined,
message: '',
errorCode: ''
}
private context = getContext(this) as common.UIAbilityContext
async aboutToAppear() {
await this.initializeDatabase();
if (this.isDatabaseReady) {
await this.getSysDictdata();
await this.loadTableData();
}
}
// 初始化数据库
async initializeDatabase() {
console.log("准备连数据库了!!!")
this.isLoading = true
try {
const context = getContext(this) as common.Context
this.isDatabaseReady = await UserRepository.initialize(context)
if (this.isDatabaseReady) {
promptAction.showToast({
message: '数据库初始化成功',
duration: 2000
})
} else {
promptAction.showToast({
message: '数据库初始化失败',
duration: 2000
})
}
} catch (error) {
promptAction.showToast({
message: '初始化数据库时出错',
duration: 2000
})
} finally {
this.isLoading = false
}
}
// 加载表格数据
async loadTableData() {
this.isLoading = true
let status = 0;
if (this.currentMenu === 'check-record') { //'检查记录'
status = 0;
} else if (this.currentMenu === 'review-record') { //复查记录
status = 2;
} else if (this.currentMenu === 'done-record') { //已办记录
status = 1;
}
try {
const paginationParams: PaginationParams = {
page: this.currentPage,
pageSize: this.pageSize,
inspection_no: this.searchForm.id || undefined,
inspection_region: this.searchForm.area || undefined,
create_time: this.searchForm.date || undefined,
status: status
}
this.inspectionlogsResult = await UserRepository.getInspectionLogs(paginationParams);
if (this.inspectionlogsResult.success && this.inspectionlogsResult.data) {
this.inspectionLog = this.inspectionlogsResult.data;
this.totalRecords = this.inspectionlogsResult.total;
this.totalPages = this.inspectionlogsResult.totalPages;
// promptAction.showToast({
// message: `查询成功,共${this.totalRecords}条记录`,
// duration: 2000
// });
} else {
promptAction.showToast({
message: this.inspectionlogsResult.message,
duration: 2000
});
}
} catch (error) {
console.error('获取检查表失败:', error)
promptAction.showToast({
message: '查询失败,请重试',
duration: 2000
});
} finally {
this.isLoading = false
}
}
// 获取码表数据
async getSysDictdata() {
this.isLoading = true
try {
this.sysDictDataResult = await UserRepository.getDictDatas('jcqy');
if (this.sysDictDataResult.data) {
this.sysDictdata = this.sysDictDataResult.data;
}
console.info('获取成功!!:', this.sysDictdata.length);
if (this.sysDictDataResult.success) {
promptAction.openToast({
message: "获取码表数据成功",
duration: 2000
});
} else {
promptAction.openToast({
message: this.sysDictDataResult.message,
duration: 2000
});
}
} catch (error) {
console.error('获取码表数据失败:', error)
} finally {
this.isLoading = false
}
}
// 添加测试数据
async addSysDictdata() {
const dictDataList: SysDictData[] = [
{
dict_sort: "1",
dict_label: "检查区域1",
dict_value: "检查区域1",
dict_type: "jcqy",
},
{
dict_sort: "2",
dict_label: "检查区域2",
dict_value: "检查区域2",
dict_type: "jcqy",
},
{
dict_sort: "3",
dict_label: "检查区域3",
dict_value: "检查区域3",
dict_type: "jcqy",
},
{
dict_sort: "1",
dict_label: "条1",
dict_value: "条1",
dict_type: "ft",
},
{
dict_sort: "2",
dict_label: "条2",
dict_value: "条2",
dict_type: "ft",
},
{
dict_sort: "3",
dict_label: "条3",
dict_value: "条3",
dict_type: "ft",
},
{
dict_sort: "1",
dict_label: new Date().getFullYear().toString(),
dict_value: "00000",
dict_type: "bh",
}
];
for (const data of dictDataList) {
await UserRepository.addSysDictData(data);
}
promptAction.showToast({
message: '测试数据添加成功',
duration: 2000
});
}
// 获取编号
async getBh() {
try {
this.bh = await UserRepository.getBh();
console.log('获取编号成功:', this.bh)
} catch (error) {
console.error('获取编号失败:', error)
}
}
// 获取前一天日期的方法
private getYesterdayDate(): string {
const yesterday = new Date();
// yesterday.setDate(yesterday.getDate() - 2);
yesterday.setDate(yesterday.getDate());
return yesterday.toISOString().split('T')[0];
}
// 添加新检查
async addInspectionLogs() {
try {
await this.getBh();
const inspectionQuestions: InspectionQuestion[] = [
{
inspection_id: 0,
question_pic: "图片路径1,图片路径2",
question_czwt: JSON.stringify([
{ "question": "存在问题1", "ft": "相关条1" },
{ "question": "存在问题2", "ft": "相关条2" }
])
}
];
const newInspectionLog: InspectionLog = {
inspection_no: this.bh,
inspection_dep: "部门",
inspection_name: "人",
inspection_date: this.getYesterdayDate(),
inspection_region: "区域",
inspection_address: "详细地址",
inspection_zrr: "责任人",
inspection_zgyj: "意见",
status: 1,
inspection_endDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0],
inspectionQuestion: inspectionQuestions
}
const result = await UserRepository.addInspectionLog(newInspectionLog)
if (result.success) {
const inspectionlogsoid = JSON.parse(result.message) as Inspectionlogsoid
promptAction.showToast({
message: `添加表成功,ID: ${inspectionlogsoid.oid}`,
duration: 2000
});
// 刷新列表
await this.loadTableData();
} else {
promptAction.showToast({
message: result.message,
duration: 2000
});
}
} catch (error) {
console.error('添加记录失败:', error)
promptAction.showToast({
message: '添加失败,请重试',
duration: 2000
});
}
}
// 菜单切换
corder(menu: string) {
this.currentMenu = menu
this.dataList = true
this.currentPage = 1 // 重置到第一页
this.loadTableData()
}
// 查询
handleSearch() {
this.currentPage = 1 // 重置到第一页
this.loadTableData()
}
// 重置查询
handleReset() {
this.searchForm = new SearchForm()
this.currentPage = 1
this.loadTableData()
}
// 新登记
handleNewRegister() {
this.formPd = '修改'
this.dataList = false
router.pushUrl({
url: 'pages/DetailPage'
})
}
// 查看
handleView(item: InspectionLog) {
this.formPd = '查看'
this.dataList = false
console.log('查看记录:', item.id)
// 跳转到详情页面
}
// 修改
handleEdit(item: InspectionLog) {
this.formPd = '修改'
this.dataList = false
console.log('修改记录:', item.id)
// 跳转到编辑页面
}
// 复查
handleEditFuCa(item: InspectionLog) {
this.formPd = '复查'
this.dataList = false
console.log('复查记录:', item.id)
// 跳转到复查页面
}
// 分页操作
handleFirstPage() {
this.currentPage = 1
this.loadTableData()
}
handlePrevPage() {
if (this.currentPage > 1) {
this.currentPage--
this.loadTableData()
}
}
handleNextPage() {
if (this.currentPage < this.totalPages) {
this.currentPage++
this.loadTableData()
}
}
handleLastPage() {
this.currentPage = this.totalPages
this.loadTableData()
}
handlePageJump(page: number) {
if (page >= 1 && page <= this.totalPages) {
this.currentPage = page
this.loadTableData()
}
}
build() {
Column() {
// 顶部栏
this.TopBar()
// 主体区域
Row() {
// 左侧导航
this.Sidebar()
// 右侧内容区
if (this.isLoading && this.inspectionLog.length === 0) {
this.LoadingState()
} else if (!this.isDatabaseReady) {
this.ErrorState('数据库未就绪')
} else {
this.ContentArea()
}
}
.layoutWeight(1)
.width('100%')
}
.width('100%')
.height('100%')
.backgroundColor('#F5F7FA')
}
[@Builder](/user/Builder)
TopBar() {
Row() {
Image($r('app.media.navleft'))
.height('100%')
.objectFit(ImageFit.Contain)
Image($r('app.media.bt_bjlk'))
.width(350)
.height(50)
.position({ x: 0, y: 0 })
.objectFit(ImageFit.Contain)
}
.height(43)
.width('100%')
.backgroundColor('#0C9D72')
}
[@Builder](/user/Builder)
Sidebar() {
Column() {
// 标题
Row() {
Image($r('app.media.left_jt'))
.width(15)
.height(15)
Text('标题')
.fontSize(14)
.fontColor('#FFFFFF')
.margin({ left: 10 })
}
.width('100%')
.padding({ left: 10, top: 5, bottom: 5 })
.backgroundColor('#52BF97')
.alignItems(VerticalAlign.Center)
// 菜单项
this.MenuItem('check-record', $r('app.media.foreground'), '记录1')
this.MenuItem('review-record', $r('app.media.foreground'), '记录2')
this.MenuItem('done-record', $r('app.media.foreground'), '已办记录')
}
.width('15%')
.height('100%')
.backgroundColor('#EEEEEE')
.border({ width: { right: 1 }, color: { right: '#868686' } })
}
[@Builder](/user/Builder)
MenuItem(menuType: string, icon: Resource, text: string) {
Row() {
Image(icon)
.width(15)
.height(15)
.margin({ left: 10, right: 5 })
Text(text)
.fontSize(14)
.fontColor(this.currentMenu === menuType ? '#FFFFFF' : '#333333')
}
.width('100%')
.padding({ top: 5, bottom: 5 })
.backgroundColor(this.currentMenu === menuType ? '#0C9D72' : '#EEEEEE')
.border({ width: { bottom: 1 }, color: { bottom: '#868686' } })
.alignItems(VerticalAlign.Center)
.onClick(() => {
this.corder(menuType)
})
}
[@Builder](/user/Builder)
ContentArea() {
Column() {
// 标题区域
this.TitleArea()
// 搜索区域
if (this.dataList) {
this.SearchArea()
}
// 表格区域
if (this.dataList) {
this.TableArea()
}
// 分页区域
if (this.dataList) {
this.PaginationArea()
}
}
.width('85%')
.backgroundColor('#FFFFFF')
}
[@Builder](/user/Builder)
TitleArea() {
Row() {
Image($r('app.media.foreground'))
.width(10)
.height(10)
.margin({ left: 10, right: 4 })
if (this.currentMenu === 'check-record') {
Text('记录1')
.fontWeight(FontWeight.Bold)
.fontSize(16)
} else if (this.currentMenu === 'review-record') {
Text('记录2')
.fontWeight(FontWeight.Bold)
.fontSize(16)
} else if (this.currentMenu === 'done-record') {
Text('已办记录')
.fontWeight(FontWeight.Bold)
.fontSize(16)
}
}
.width('100%')
.height(30)
.backgroundColor('#EEEEEE')
.alignItems(VerticalAlign.Center)
}
[@Builder](/user/Builder)
SearchArea() {
Column() {
Flex({
direction: FlexDirection.Row,
wrap: FlexWrap.Wrap,
justifyContent: FlexAlign.Start,
alignItems: ItemAlign.Center
}) {
// 编号输入
this.SearchItem('编号', 'id', '请输入编号')
// 区域输入
this.AreaFilter();
// 登记时间选择
this.DatePickerItem()
// 按钮组
this.ButtonGroup()
}
.width('100%')
}
.width('100%')
.padding(10)
.margin({ top: 10, left: 8, right: 8 })
.backgroundColor('#EEEEEE')
}
[@Builder](/user/Builder)
SearchItem(label: string, field: string, placeholder: string) {
Row() {
Text(label)
.fontSize(15)
.fontColor('#333333')
.width(60)
.textAlign(TextAlign.End)
.margin({ right: 8 })
TextInput({ placeholder: placeholder, text: this.getFieldValue(field) })
.onChange((value: string) => {
this.setFieldValue(field, value)
})
.width(150)
.height(32)
.border({ width: 1, color: '#DDDDDD' })
.borderRadius(4)
.padding(4)
.fontSize(12)
}
.margin({ right: 16, bottom: 8 })
.alignItems(VerticalAlign.Center)
}
[@Builder](/user/Builder)
DatePickerItem() {
Row() {
Text('登记时间')
.fontSize(15)
.fontColor('#333333')
.width(60)
.textAlign(TextAlign.End)
.margin({ right: 8 })
Text(this.searchForm.date || '请选择登记日期')
.width(150)
.backgroundColor('#FFFFFF')
.border({ width: 1, color: '#DDDDDD' })
.borderRadius(0)
.padding(5)
.onClick(() => {
this.uiContext.showDatePickerDialog({
start: new Date('2000-01-01'),
selected: new Date(),
onAccept: (value: Date更多关于HarmonyOS 鸿蒙Next中子组件没有按照起始端对齐的实战教程也可以访问 https://www.itying.com/category-93-b0.html
你可以吧代码打包发出来,我用你的代码跑不起来1
更多关于HarmonyOS 鸿蒙Next中子组件没有按照起始端对齐的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
谢谢已经解决了,
已处理将TableArea整体改造即可
@Builder
TableArea() {
Column() {
// 表头 - 固定高度
this.TableHeader()
// 表格内容 - 使用剩余空间
Column() {
if (this.inspectionLog.length > 0) {
List({ space: 0 }) {
ForEach(this.inspectionLog, (item: InspectionLog, index: number) => {
ListItem() {
this.TableRow(item, index)
}
}, (item: InspectionLog) => item.id?.toString() ?? Math.random().toString())
}
.width('100%')
.layoutWeight(1)
} else {
this.EmptyState()
}
}
.width('100%')
.layoutWeight(1)
.alignItems(HorizontalAlign.Start)
}
.width('100%')
.height('70%')
.margin({
top: 10,
left: 8,
right: 8,
bottom: 8
})
.border({ width: 1, color: '#DDDDDD' })
}
将tableRow外层的Row设置justifyContent(FlexAlign.Start),删除里面Text中的textAlign(TextAlign.Center)
@Builder
TableRow(item: InspectionLog, index: number) {
Row() {
Text(item.inspection_no || ‘-’)
.width(‘13%’)
.fontSize(15)
.textAlign(TextAlign.Center) //删除文字在Text组件居中显示,默认为TextAlign.Start居左
.padding(8)
.border({ width: { right: 1 }, color: ‘#DDDDDD’ })
Text(item.inspection_dep || ‘-’)
.width(‘15%’)
.fontSize(15)
.textAlign(TextAlign.Center)
.padding(8)
.border({ width: { right: 1 }, color: ‘#DDDDDD’ })
Text(item.inspection_name || ‘-’)
.width(‘12%’)
.fontSize(15)
.textAlign(TextAlign.Center)
.padding(8)
.border({ width: { right: 1 }, color: ‘#DDDDDD’ })
Text(item.inspection_region || ‘-’)
.width(‘15%’)
.fontSize(15)
.textAlign(TextAlign.Center)
.padding(8)
.border({ width: { right: 1 }, color: ‘#DDDDDD’ })
Text(item.inspection_date || ‘-’)
.width(‘15%’)
.fontSize(15)
.textAlign(TextAlign.Center)
.padding(8)
.border({ width: { right: 1 }, color: ‘#DDDDDD’ })
Text(this.getStatusText(item.status))
.width(‘10%’)
.fontSize(15)
.textAlign(TextAlign.Center)
.padding(8)
.border({ width: { right: 1 }, color: ‘#DDDDDD’ })
this.OperationButtonsWithStyle(item)
}
.width(‘100%’)
.justifyContent(FlexAlign.Start) //新增,元素在水平方向左对齐
您好 我的问题并不是元素内部左对齐或者是居中对齐的问题,是我整个列表内容在呈现上并没有紧贴表头,
在HarmonyOS鸿蒙Next中,子组件未按起始端对齐通常是由于布局容器属性设置问题。检查父容器的alignItems属性是否设为HorizontalAlign.Start或VerticalAlign.Top。若使用Flex布局,确认justifyContent设为FlexAlign.Start。对于Stack组件,需设置alignContent为起始对齐方式。同时验证子组件的尺寸和位置属性是否冲突,例如width、height或margin可能影响对齐效果。
在您的代码中,表格行没有按照起始端对齐的主要原因是 TableArea 中的布局设置问题。
具体分析:
-
Scroll容器内的Column布局:在
TableArea的Scroll容器内,您使用了Column来包裹表格行,但没有设置正确的对齐方式。 -
默认对齐方式:Column 默认是垂直居中对齐的,这导致表格行在滚动区域内垂直居中显示,而不是从顶部开始排列。
解决方案:
修改 TableArea 中的 Scroll 容器部分:
@Builder
TableArea() {
Column() {
// 表头
this.TableHeader()
// 表格内容
Scroll() {
Column() {
if (this.inspectionLog.length > 0) {
ForEach(this.inspectionLog, (item: InspectionLog, index: number) => {
this.TableRow(item, index)
}, (item: InspectionLog) => item.id?.toString() ?? Math.random().toString())
} else {
this.EmptyState()
}
}
.width('100%')
.alignItems(HorizontalAlign.Start)
.justifyContent(FlexAlign.Start) // 添加这行确保从顶部开始
}
.scrollBar(BarState.On)
.layoutWeight(1)
}
.width('100%')
.layoutWeight(1)
.margin({
top: 10,
left: 8,
right: 8,
bottom: 8
})
.border({ width: 1, color: '#DDDDDD' })
}
关键修改:
- 添加
.justifyContent(FlexAlign.Start)确保内容从容器顶部开始排列 - 保持
.alignItems(HorizontalAlign.Start)确保水平方向也从左侧开始
这样修改后,表格行就会从滚动区域的顶部开始排列,实现您期望的起始端对齐效果。

