Аватар с круговым переполнением, накладываемый на контейнер

#flutter #overlay

#оверлей #наложение

Вопрос:

Вот дизайн, который я хочу создать:

Изображение

Вот где я сейчас:

Изображение

Когда я попытался обернуть размерную рамку CircleAvatar с помощью Overflow Box, я получил ошибку «RenderFlex, переполненный бесконечными пикселями внизу«. Я пытался использовать stack, но понимаю, что это усложняет ситуацию. Я чувствую, что окно переполнения — это ответ, но я не мог разобраться в этом.

 Container(
  child: Column(
    crossAxisAlignment: CrossAxisAlignment.stretch,
    children: [
      SizedBox(
        child: CircleAvatar(
          radius: 40.0,
          backgroundColor: Colors.white,
          child: CircleAvatar(
            child: Align(
              alignment: Alignment.bottomRight,
              child: CircleAvatar(
                backgroundColor: Colors.white,
                radius: 12.0,
                child: Icon(
                  Icons.camera_alt,
                  size: 15.0,
                  color: Color(0xFF404040),
                ),
              ),
            ),
            radius: 38.0,
            backgroundImage: AssetImage(
              'assets/images/user-image-default.png'),
          ),
        ),
      ),
      Center(
        child: Container(
          padding: EdgeInsets.only(top: 16.0),
          child: Text(
            'Hi Sir David',
            style: TextStyle(
              fontFamily: 'SF Pro',
              fontWeight: FontWeight.w700,
              fontSize: 24.0,
            ),
          ),
        ),
      ),
      Center(
        child: Container(
          padding: EdgeInsets.only(top: 8.0),
          child: Text(
            'Wildlife Advocate',
            style: TextStyle(
              fontFamily: 'SF Pro',
              fontSize: 12.0,
            ),
          ),
        ),
      ),
      Center(
        child: Padding(
          padding: const EdgeInsets.all(24.0),
            child: TextButton(
              onPressed: () {
                print('im pressed');
              },
              child: Container(
                padding:
                EdgeInsets.fromLTRB(16.0, 8.0, 16.0, 8.0),
                decoration: BoxDecoration(
                  color: Color(0xFFEF476F),
                  borderRadius:
                  BorderRadius.all(Radius.circular(20.0)),
                ),
                child: Text(
                  'Edit Profile',
                  style: TextStyle(
                    fontFamily: 'SF Pro',
                    color: Colors.white,
                    fontWeight: FontWeight.w500,
                    fontSize: 16.0,
                  ),
                ),
              ),
            ),
        ),
      ),
    ],
  ),
  margin: EdgeInsets.all(16.0),
  decoration: BoxDecoration(
    color: Colors.white,
    borderRadius: BorderRadius.circular(16.0),
  ),
),
  

Ответ №1:

Я не привожу полный код вашего примера, но это может вам помочь. Я просто кодирую этот dartpad и, надеюсь, он обеспечивает решение…

 Stack(
  children: [
    
    Container(
      margin: EdgeInsets.only(top: 48),
    height: 300,decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16.0),
),),
    Align(
      alignment: Alignment.topCenter,
    child: SizedBox(
    child: CircleAvatar(
      radius: 40.0,
      backgroundColor: Colors.white,
      child: CircleAvatar(
        child: Align(
          alignment: Alignment.bottomRight,
          child: CircleAvatar(
            backgroundColor: Colors.white,
            radius: 12.0,
            child: Icon(
              Icons.camera_alt,
              size: 15.0,
              color: Color(0xFF404040),
            ),
          ),
        ),
        radius: 38.0,
        backgroundImage: AssetImage(
          'assets/images/user-image-default.png'),
      ),
    ),)
  ),
  ]
)
  

Ответ №2:

Если эти методы не работают, вам следует обернуть два виджета (т.Е. виджеты, которые вы хотите сложить вместе) виджетом «Позиционированный», чтобы узнать больше об этом, нажмите на ссылку ниже:

https://www.youtube.com/watch?v=7njbf2mFcgM

Ответ №3:

Я вижу, что вы хотите, чтобы два элемента накладывались друг на друга. В таких случаях Stack виджет может оказаться полезным. Stack принимает массив children для сложения. По сути, 2 компонента, которые вы хотите сложить CircleAvatar , — это карта и карта Container под ней. Кроме того, поскольку по умолчанию виджеты выровнены по верхнему левому краю, вы можете выровнять его по центру сверху. Вы можете использовать alignment свойство и установить для него Alignment.topCenter значение, чтобы выровнять его соответствующим образом.

Структура кода


Собрав все это вместе, вы получите вот такую структуру:

 Container(
  margin: EdgeInsets.all(16.0),
  child: Stack(
    alignment: Alignment.topCenter,
    children: [
      // Avatar

      SizedBox(
        child: CircleAvatar(
          ...
        )
      ),

      // Card Container

      Container(
        child: Column(
          children: [
            // All the widgets after `CircleAvatar` goes here
            ⋮
            ⋮
          ]
        ),
        margin: EdgeInsets.only(top: 16.0),    // Change this based on the spacing between the card container and the avatar
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(16.0),
        ),
      )
    )
  )
);
  

Примечание:

  • В зависимости от того, как все это выравнивается, вы можете изменить значение верхнего поля. Предоставленный аватар следует рассматривать только как заполнитель.

  • Этот ответ просто предоставляет структуру кода, чтобы он выглядел чистым и понятным.

Ответ №4:

 Align(
alignment: Alignment.TopCenter,
 child: CircleAvatar(
   radius: 70,
   backgroundImage: AssetImage('assets/images/avatart.jpg'),
   backgroundColor: kPrimaryColor,
 ),
),