View

300x250

별 거 아닌 것 같은데, 요걸 구현하면서 4시간 정도 삽질을 했다. 후… 그래서 누군가 찾아보지 않을까 싶어서 기록을 남겨둔다!

아래 이미지처럼 나타나지는 위젯을 만들고싶었다.

Untitled.png

이걸 분석해봤을 때, 요구조건은 아래와 같다.

  1. Row의 Children에 들어가서 Cell로 작동해야 한다.
  2. Row의 자식으로, 한 줄 전체를 사용한다.
  3. 말풍선의 가장 오른쪽에는 이미지가 들어간다.
  4. 텍스트의 길이에 따라 말풍선의 길이가 달라진다. ← 이게 진짜 열받음

요걸 구현하기 위해서 Row 내에 Cell로 (1번 조건) Expanded가 들어가고 (전체 한 줄을 사용하기 위해 - 2번 조건 ), Expanded 내에 다시 Row를 넣고 (이미지와 텍스트를 배치하기 위해 - 3번 조건), 텍스트에 Expanded로 적당히 Fit 하게 필요한 공간만 사용하도록 만들고자 했다.

Expanded 자체가 자유롭게 공간이 늘어나도록 만들어주기 때문에, Expanded 안에 Row 안에 Expanded를 넣는 경우에 해당 영역의 최대 길이를 infinity로 인식하면서 constraint를 넘어가버리는 문제가 많았다…! 그래서 찾은 방법은 LayoutBuilder를 사용해서 부모 뷰가 가지고 있는 크기를 받아와 제한을 걸어주는 방식이였다.

또, mainAxisSize: MainAxisSize.min 라는 속성을 사용하면 필요한 만큼만 공간을 차지하도록 크기를 줄여벼릴 수도 있어서, 요걸 적용해 해결하였다. 이런 속성이 있다는 건 이번에 처음 알았다.

Row(
  mainAxisSize: MainAxisSize.min,
  children: [
    Padding(
      padding: EdgeInsets.only(right: 8.0),
      child: CircleAvatar(
        radius: profileImageRadius,
        foregroundImage: NetworkImage(
          'https://health.chosun.com/site/data/img_dir/2023/07/17/2023071701753_0.jpg',
        ),
      ),
    ),
    Expanded(
      child: Container(
        height: 47,
        child: LayoutBuilder(
          builder: (BuildContext context, BoxConstraints constraints) {
            print(constraints.maxWidth);
            return Container(
              child: Stack(
                children: [
                  Container(
                    decoration: BoxDecoration(
                      color: Colors.blue,
                      borderRadius: BorderRadius.all(
                        Radius.circular(10.0),
                      ),
                    ),
                    child: Padding(
                      padding: const EdgeInsets.all(4.0),
                      child: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          Flexible(
                            child: Container(
                              constraints:
                                  BoxConstraints(minWidth: 120),
                              child: Padding(
                                padding: const EdgeInsets.all(2.0),
                                child: Column(
                                  crossAxisAlignment:
                                      CrossAxisAlignment.start,
                                  children: [
                                    Text(
                                      "Name",
                                      overflow: TextOverflow.ellipsis,
                                      maxLines: 1,
                                    ),
                                    Text(
                                      "도전 목표",
                                      overflow: TextOverflow.ellipsis,
                                      maxLines: 1,
                                    ),
                                  ],
                                ),
                              ),
                            ),
                          ),
                          Container(
                            decoration: BoxDecoration(
                                borderRadius: BorderRadius.all(
                                  Radius.circular(10.0),
                                ),
                                boxShadow: [
                                  BoxShadow(
                                      color: Colors.black26,
                                      spreadRadius: 2,
                                      blurRadius: 2,
                                      offset: Offset(0, 2))
                                ]),
                            clipBehavior: Clip.hardEdge,
                            child: Image(
                              width: 50,
                              height: 37,
                              fit: BoxFit.fill,
                              image: NetworkImage(
                                'https://health.chosun.com/site/data/img_dir/2023/07/17/2023071701753_0.jpg',
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                ],
              ),
            );
          },
        ),
      ),
    ),
  ],
),

아래처럼, Text의 길이에 대응해 길이가 늘어나고, ellipsis가 생기는 것을 확인할 수 있다!

Untitled.png

320x100
Share Link
reply
반응형
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31