Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ConstraintLayout 能放在listview里面用吗 #11

Open
qflbai opened this issue Aug 1, 2022 · 12 comments
Open

ConstraintLayout 能放在listview里面用吗 #11

qflbai opened this issue Aug 1, 2022 · 12 comments

Comments

@qflbai
Copy link

qflbai commented Aug 1, 2022

No description provided.

@hackware1993
Copy link
Owner

可以

@qflbai
Copy link
Author

qflbai commented Aug 2, 2022

`class VisualizeReportedRecordWidget extends StatelessWidget {
final VisualizeReportedRecordReq visualizeReportedRecordReq;

const VisualizeReportedRecordWidget(
{required this.visualizeReportedRecordReq, Key? key})
: super(key: key);

@OverRide
Widget build(BuildContext context) {
var idImage1 = ConstraintId("idImage1");
var idRow1 = ConstraintId("idRow1");
var idStoreName = ConstraintId("idStoreName");
var idComment = ConstraintId("idComment");
var idPhoto = ConstraintId("idPhoto");
var idSb1 = ConstraintId("idSb1");

var time = getFormatDateC3().safetyFormat(
    getFormatDateFinal().safetyParse(visualizeReportedRecordReq.ctime));

var checkTime = "";
var state = "";
var checker = '';
var isShowState = true;
var isShowCommon = true;
var comment = "";
switch (visualizeReportedRecordReq.status) {
  case 2:
    checker = visualizeReportedRecordReq.operatorName ?? "";
    checkTime = getFormatDateC1().safetyFormat(
        getFormatDateFinal().safetyParse(visualizeReportedRecordReq.utime));
    state = AdS.of(context).adHint196();
    comment = visualizeReportedRecordReq.operatorRemark ?? "";
    break;
  case 5:
    checker = visualizeReportedRecordReq.operatorName ?? "";
    checkTime = getFormatDateC1().safetyFormat(
        getFormatDateFinal().safetyParse(visualizeReportedRecordReq.utime));
    state = AdS.of(context).adHint197();
    comment = visualizeReportedRecordReq.operatorRemark ?? "";
    break;

  default:
    isShowState = false;
    isShowCommon = false;
    break;
}

var storeName = visualizeReportedRecordReq.store ?? "";

List<AssetsInfo> assetsInfoList = [];
visualizeReportedRecordReq.img?.split("|").map((e) {
  AssetsInfo assets = AssetsInfo();
  assets.serverUrl = e;
  assetsInfoList.add(assets);
}).toList();

return ConstraintLayout(
  height: wrapContent,
  children: [
    Image.asset(
      ImagePath.wrapAssetsPng("ad_ic_flow_chapter"),
      width: 20,
      height: 20,
      package: AdConfigs.package,
    ).apply(
        constraint: Constraint(
            id: idImage1,
            top: parent.top,
            left: parent.left,
            margin: const EdgeInsets.only(left: 16, top: 4))),
    Row(
      children: [
        Text(
          time,
          style: const TextStyle(
              color: ColorsHelper.color333333,
              fontSize: 18,
              fontWeight: FontWeight.bold),
        ),
        const SizedBox(
          width: 8,
        ),
        if (isShowState)
          Container(
            padding: const EdgeInsets.symmetric(horizontal: 4),
            decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(1),
                border: Border.all(
                    color: ColorsHelper.colorFF4545, width: 0.5)),
            child: Text(
              state,
              style: const TextStyle(
                  color: ColorsHelper.colorFF4545, fontSize: 12),
            ),
          )
      ],
    ).apply(
        constraint: Constraint(
            id: idRow1,
            left: idImage1.right,
            top: idImage1.top,
            margin: const EdgeInsets.only(left: 12),
            bottom: idImage1.bottom)),
    Text(
      storeName,
      style: const TextStyle(color: ColorsHelper.color666666, fontSize: 12),
    ).apply(
        constraint: Constraint(
            id: idStoreName,
            left: idRow1.left,
            top: idRow1.bottom,
            margin: const EdgeInsets.only(top: 4))),
    Container(
      decoration: BoxDecoration(
          color: ColorsHelper.colorF4F4F4,
          borderRadius: BorderRadius.circular(2)),
      padding: const EdgeInsets.all(10),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            mainAxisSize: MainAxisSize.max,
            children: [
              ccImage(ImagePath.wrapAssetsPng('ad_ic_head_photo'),
                  package: AdConfigs.package,
                  width: 32,
                  borderRadius: BorderRadius.circular(2)),
              const SizedBox(
                width: 4,
              ),
              Expanded(
                  child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Row(
                    children: [
                      Text(
                        AdS.of(context).adHint195(),
                        style: const TextStyle(
                            color: ColorsHelper.color333333, fontSize: 14),
                      ),
                      Expanded(
                          child: Text(
                        checkTime,
                        textAlign: TextAlign.end,
                        style: const TextStyle(
                            color: ColorsHelper.color999999, fontSize: 12),
                      ))
                    ],
                  ),
                  Text(
                    checker,
                    style: const TextStyle(
                        color: ColorsHelper.color999999, fontSize: 12),
                  )
                ],
              )),
            ],
          ),
          const SizedBox(
            height: 10,
          ),
          const CCDivider(
            color: ColorsHelper.colorE0E0E0,
          ),
          const SizedBox(
            height: 10,
          ),
          Text(
            comment,
            style: const TextStyle(
                color: ColorsHelper.color666666, fontSize: 14),
          ),
        ],
      ),
    ).apply(
        constraint: Constraint(
            id: idComment,
            left: idRow1.left,
            top: idStoreName.bottom,
            right: parent.right,
            width: matchConstraint,
            visibility:
                isShowCommon ? CLVisibility.visible : CLVisibility.gone,
            margin: const EdgeInsets.only(right: 16, top: 12))),
    ShowMediaWidget(
      isEnable: false,
      assetsInfoList: assetsInfoList,
      maxSize: 96,
      padding: EdgeInsets.zero,
    ).apply(
        constraint: Constraint(
      id: idPhoto,
      top: idComment.bottom,
      left: idRow1.left,
      width: matchConstraint,
      right: parent.right,
      margin: const EdgeInsets.only(right: 16),
      goneMargin: const EdgeInsets.only(top: 12),
    )),
    const SizedBox(
      height: 24,
    ).apply(
        constraint:
            Constraint(id: idSb1, left: idRow1.left, top: idPhoto.bottom)),
    const CCVerticalDivider(
      width: 1,
      color: ColorsHelper.colorE0E0E0,
    ).apply(
      constraint: Constraint(
          id: ConstraintId("sb2"),
          left: idImage1.left,
          right: idImage1.right,
          top: idImage1.bottom,
          bottom: idSb1.bottom,
          height: matchConstraint,
          margin: const EdgeInsets.only(top: 4)),
    ),
  ],
);

}
}`

您好,当我在listview里面使用该布局时,高的wrapContent不起作用,怎么调试都是44.5。请问是有什么限制导致的吗。期待你的答复。
1659405198715

924ae302101c36f1635d8e0cab3d9b5

@hackware1993
Copy link
Owner

你用错了,当你把 ConstraintLayout 的高度设置为 wrapContent 时,ConstraintLayout 的自身大小是由那些宽高为 wrapContent 或 fixed size 的子元素的大小(以及它们的 margin)撑起来的。那些宽高为 matchParent 或 matchConstraint 的子元素不会影响 ConstraintLayout 的自身大小。

如果一部分子元素相对于顶部对齐,一部分相对于底部对齐,是不会把 ConstraintLayout 撑到你的预期大小的。

你的布局方式应该改为始终相对于一个方向去对齐。

@qflbai
Copy link
Author

qflbai commented Aug 2, 2022

好的,谢谢您的解惑。

@qflbai qflbai closed this as completed Aug 2, 2022
@hackware1993 hackware1993 reopened this Aug 2, 2022
@hackware1993
Copy link
Owner

钉在这里,供后面的小伙伴参考。

@hackware1993 hackware1993 pinned this issue Aug 2, 2022
@qflbai
Copy link
Author

qflbai commented Aug 2, 2022

ConstraintLayout( height: wrapContent, children: [ Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( height: 20, ), Text("test"), Container( child: Text("test2"), ), Container( color: Colors.redAccent, child: Text("test3"), ) ], ).applyConstraint( id: idColumn, top: parent.top, left: parent.left, height: wrapContent, width: matchConstraint, right: parent.right), ], )

您好,我还想再请教一下。我的布局想这样的,放在listview里面, 高度设置为wrapContent,这时高度是计算不出来的吗?,导致界面啥也不显示。
1659412623376
0341229d98c0c59a3c1e6f6a5eb642d

@hackware1993
Copy link
Owner

稍等我研究下

@hackware1993
Copy link
Owner

          ).applyConstraint(
            // id: idColumn,
            top: parent.top,
            // left: parent.left,
            height: wrapContent,
            width: matchParent,
            // width: matchConstraint,
            // right: parent.right,
          ),
        ],

改成这样就好了。宽度从 matchConstraint 改为 matchParent,删除横向的约束

@hackware1993
Copy link
Owner

hackware1993 commented Aug 2, 2022

这里牵扯到布局优先级的问题,整个 ConstraintLayout 中只有一个子元素,这里要指望 Column 把 ConstraintLayout 撑起来,那么 Column 的宽度就不能再是 matchConstraint,因为这样会让 parent 先布局,Column 后布局。这导致 parent 没有被任何元素撑起来,实际宽高为 0。就导致什么也展示不出来了 。我后面会写一篇原理分析的文章好好讲讲这些 “有坑” 的注意点。

@hackware1993
Copy link
Owner

约束布局的核心原理是按照优先级来布局,A 约束在 B 的右边,则 A 的布局优先级比 B 低。也就是要等 B 布局之后再布局 A。

你这里在横向上把宽高设为 matchConstraint,导致 Column 和 parent 产生了约束依赖关系,parent 的布局优先级高于 Column。因为要等 parent 的 left 和 right 确定以后,才能确定 Column 的宽度。

当你改用 matchParent 以后,横向上的约束依赖关系就被打破了,因为在布局 Column 时可以拿到 parent 的宽度,也就是 ListView 的宽度。这就使得 Column 可以先于 parent 布局,parent 就能被撑起来,界面展示就恢复正常了!

@hackware1993
Copy link
Owner

其实最主要的还是约束布局的约束推断算法不够聪明,不然你这么写也可以保证不出问题的

@qflbai
Copy link
Author

qflbai commented Aug 2, 2022

根据您的详细的回复,我解决了我项目中遇到的问题,谢谢您!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants