# 10.通过联系人Cell看断言

### 前言

我们在构建如微信联系人页类似的 Cell 时，主要有两种。一种是加载网络图片，用来现实我们的联系人；一种是本地图片，用来显示一些系统入口，如公众号等。那么如何优雅的完成这样对两种形式数据展示的 Cell 呢？借助这个场景，我们来了解一下 `断言` 。

![1](/files/EuY3CVPWwW7XNw9UaEFK)

### 不使用断言

这样的代码，并没有什么明显问题。

* 普通联系人传入 avatarUrl 网络图片
* 系统入口传入 assetName 资源名称
* avatarUrl 和 assetName 都是可选字段，即均可为空

这样的隐患是无法保证至少有一个是有值的。下面我们使用断言进行优化，如果两者都为空就会抛出异常。

```
class _ContactCell extends StatelessWidget {
  const _ContactCell({
    required this.name,
    this.avatarUrl,
    this.assetName,
  });

  final String name;
  final String? avatarUrl;
  final String? assetName;

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 60,
      color: Colors.white,
      child: Stack(
        children: [
          Row(
            children: [
              Row(
                children: [
                  const SizedBox(
                    width: 12,
                  ),
                  avatarUrl != null
                      ? Container(
                          width: 48,
                          height: 48,
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(4),
                            image: DecorationImage(
                              image: NetworkImage(avatarUrl!),
                            ),
                          ),
                        )
                      : Container(),
                  assetName != null
                      ? Container(
                          width: 48,
                          height: 48,
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(4),
                            image: DecorationImage(
                              image: AssetImage(assetName!),
                            ),
                          ),
                        )
                      : Container(),
                  const SizedBox(
                    width: 12,
                  ),
                  Text(
                    name,
                    style: const TextStyle(
                      fontSize: 16,
                      fontWeight: FontWeight.w500,
                    ),
                  ),
                ],
              ),
            ],
          ),
          Positioned(
            left: 50,
            bottom: 0,
            child: Container(
              height: 1,
              color: Colors.grey,
            ),
          ),
        ],
      ),
    );
  }
}
```

### 使用断言进行优化

这里在构造方法加了断言： `assert((avatarUrl != null || assetName != null), '至少一张图片')`

如果两者都为空，那么就会抛出如图异常：

![2](/files/vc1qmKaGXEihH2GHnZSU)

```
class _ContactCell extends StatelessWidget {
  const _ContactCell({
    required this.name,
    this.avatarUrl,
    this.assetName,
  }) : assert((avatarUrl != null || assetName != null), '至少一张图片');

  final String name;
  final String? avatarUrl;
  final String? assetName;

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 60,
      color: Colors.white,
      child: Stack(
        children: [
          Row(
            children: [
              Row(
                children: [
                  const SizedBox(
                    width: 12,
                  ),
                  avatarUrl != null
                      ? Container(
                          width: 48,
                          height: 48,
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(4),
                            image: DecorationImage(
                              image: NetworkImage(avatarUrl!),
                            ),
                          ),
                        )
                      : Container(),
                  assetName != null
                      ? Container(
                          width: 48,
                          height: 48,
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(4),
                            image: DecorationImage(
                              image: AssetImage(assetName!),
                            ),
                          ),
                        )
                      : Container(),
                  const SizedBox(
                    width: 12,
                  ),
                  Text(
                    name,
                    style: const TextStyle(
                      fontSize: 16,
                      fontWeight: FontWeight.w500,
                    ),
                  ),
                ],
              ),
            ],
          ),
          Positioned(
            left: 50,
            bottom: 0,
            child: Container(
              height: 1,
              color: Colors.grey,
            ),
          ),
        ],
      ),
    );
  }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ryukiedev.gitbook.io/wiki/flutter/10.-tong-guo-lian-xi-ren-cell-kan-duan-yan.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
