如何在此头像上创建选区?

How do I create a selection on this avatar?

我正在创建一个用户最多可以选择三个头像的应用程序,我的问题是如何使头像具有以下状态:选中时,它们具有蓝色边框并且文本变为灰色 (未选中)选中后变黑?

下面是选中后的头像图片。

代码:

body: GestureDetector(
    onTap: () {},
    child: Center(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Column(
            children: [
              SizedBox(
                child: CircleAvatar(
                  backgroundColor: Color(0xfff3e0a6),
                  radius: 30.0,
                  backgroundImage: AssetImage('image/person.jpg'),
                  child: Align(
                    alignment: Alignment.bottomRight,
                    child: CircleAvatar(
                      backgroundColor: Colors.blue,
                      radius: 12.0,
                      child: Icon(
                        Icons.camera_alt,
                        size: 12.0,
                        color: Colors.white,
                      ),
                    ),
                  ),
                ),
              ),
              Padding(
                padding: EdgeInsets.all(8),
                child: Text(
                  'avatar1'
                ),
              ),
            ],
          ),
          SizedBox(width: 20,),
          Column(
            children: [
              SizedBox(
                child: CircleAvatar(
                  backgroundColor: Color(0xfff3e0a6),
                  radius: 30.0,
                  backgroundImage: AssetImage('image/person.jpg'),
                  child: Align(
                    alignment: Alignment.bottomRight,
                    child: CircleAvatar(
                      backgroundColor: Colors.blue,
                      radius: 12.0,
                      child: Icon(
                        Icons.camera_alt,
                        size: 12.0,
                        color: Colors.white,
                      ),
                    ),
                  ),
                ),
              ),
              Padding(
                padding: EdgeInsets.all(8),
                child: Text(
                    'avatar1'
                ),
              ),
            ],
          ),
          SizedBox(width: 20,),
          Column(
            children: [
              SizedBox(
                child: CircleAvatar(
                  backgroundColor: Color(0xfff3e0a6),
                  radius: 30.0,
                  backgroundImage: AssetImage('image/person.jpg'),
                  child: Align(
                    alignment: Alignment.bottomRight,
                    child: CircleAvatar(
                      backgroundColor: Colors.blue,
                      radius: 12.0,
                      child: Icon(
                        Icons.camera_alt,
                        size: 12.0,
                        color: Colors.white,
                      ),
                    ),
                  ),
                ),
              ),
              Padding(
                padding: EdgeInsets.all(8),
                child: Text(
                    'avatar1'
                ),
              ),
            ],
          ),
        ],
      ),
    ),
  ),

这是每个头像和文本在被选中时的行为方式。

使用 FocusBuilder 使小部件可聚焦。检查下面的这个例子。

import 'package:flutter/material.dart';

void main() {
  renderContainer(Widget child) {
    return SizedBox(height: 200, width: 200, child: Center(child: child));
  }

  ;
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(),
        body: Row(
          children: [
            renderContainer(SelectableAvatar()),
            renderContainer(SelectableAvatar()),
            renderContainer(SelectableAvatar()),
          ],
        ),
      ),
    ),
  );
}

class SelectableAvatar extends StatefulWidget {
  const SelectableAvatar({Key? key, this.url}) : super(key: key);
  final String? url;

  @override
  State<SelectableAvatar> createState() => _SelectableAvatarState();
}

class _SelectableAvatarState extends State<SelectableAvatar> {
  @override
  Widget build(BuildContext context) {
    return FocusScope(
      child: Focus(
        child: Builder(builder: (context) {
          final FocusNode focusNode = Focus.of(context);
          final bool hasFocus = focusNode.hasFocus;
          return GestureDetector(
            onTap: () {
              if (hasFocus) {
                focusNode.unfocus();
              } else {
                focusNode.requestFocus();
              }
            },
            child: _renderAvatar(hasFocus),
          );
        }),
      ),
    );
  }

  Widget _renderAvatar(bool hasFocus) {
    final uri = widget.url != null ? Uri.tryParse(widget.url!) : null;
    final useDefault = uri == null;

    ImageProvider getProvider() {
      if (useDefault) {
        return const AssetImage('');
      }
      return NetworkImage(widget.url!);
    }
    
    
    // Render base on hasFocus state
    return AnimatedContainer(
      duration: const Duration(milliseconds: 100),
      width: hasFocus ? 120 : 100,
      height: hasFocus ? 120 : 100,
      decoration: BoxDecoration(
        shape: BoxShape.circle,
        border: Border.all(
          width: hasFocus ? 5 : 3,
          color: hasFocus ? Colors.blue : Colors.black,
        ),
      ),
      child: CircleAvatar(
        foregroundColor: Colors.white,
        backgroundImage: getProvider(),
      ),
    );
  }
}