como mostrar um widget como um pop-up
Atualmente, tenho uma visualização em grade. Quando toco nele, navego para outra página usando um widget de herói.
Nessa página, tenho apenas um contêiner que mostra informações sobre esse bloco de grade.
O que eu quero é que esse contêiner fique no topo da visualização em grade em vez de ser uma página diferente.
Como posso estourá-lo assim? E se possível, prefiro manter a animação do herói.
Respostas
Você deve usar o método showDialog, assim:
InkWell(
child: GridItem(),
onTap: () {
showDialog(
context: context,
builder: (context) => AlertDialog(
content: Hero(child: Card(child: YourWidget()))
); // you can use SimpleDialog, specify barrier dismissible etc
},
)
Aqui está o link sobre a classe de diálogo https://api.flutter.dev/flutter/material/Dialog-class.html
Sobre o Herói, não tenho certeza, porque escrevo de cabeça, mas ele deve servir (ofc acrescente a mesma tag, você não precisa do cartão pai se o seu widget já tiver um - Hero requer um widget de Material )
Estou postando o que acabei fazendo porque funciona.
O que @Nonstapp e @Parth sugeriram funciona, exceto para a transição Hero, uma vez que se aplica apenas a PageRoutes.
Portanto, encontrei outra maneira de mostrar um pop-up semelhante com um PageRoute.
O widget de informações que estou exibindo:
return Padding(
padding: EdgeInsets.fromLTRB(
MediaQuery.of(context).size.width / 8,
MediaQuery.of(context).size.height / 4,
MediaQuery.of(context).size.width / 8,
0),
child: Material(
color: Colors.transparent,
child: ...
O preenchimento obviamente é para posicionamento e o widget de Material é para dar a ele estilo de Material e widgets habilitados como IconButton. Dê ao widget Material uma cor transparente.
É assim que eu chamo:
void seeDetails(BuildContext context, Book book) {
Navigator.push(
context,
PageRouteBuilder(
fullscreenDialog: true,
opaque: false,
pageBuilder: (_, __, ___) => ChangeNotifierProvider.value(
value: book,
child: DetailCard(),
),
),
);
}
Eu uso o PageRouter para mostrar uma caixa de diálogo em tela cheia, mas devido às minhas configurações lá, apenas o cartão de informações é visível.
A desvantagem é que não consigo ativar a barreiraDismissibles, pois estou em outra rota atm.
Este é o meu resultado:
No entanto, a solução real é a que @pskink sugeriu acima. Requer mais configuração e ajustes e tive problemas com Provedores. Aqui está como você pode implementá-lo
você pode usar a caixa de diálogo personalizada: -
onPressed: () {
showDialog(
context: context,
builder: (_) => Center(
child: RaisedButton(
child: Text("Show dialog"),
onPressed: () {
showDialog(
context: context,
builder: (context) {
return Dialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(40)),
elevation: 16,
child: Container(
height: 400.0,
width: 360.0,
child: ListView(
children: <Widget>[
SizedBox(height: 20),
Center(
child: Text(
"Leaderboard",
style: TextStyle(fontSize: 24, color: Colors.blue, fontWeight: FontWeight.bold),
),
),
SizedBox(height: 20),
_buildName(imageAsset: 'assets/chocolate.jpg', name: "Name 1", score: 1000),
_buildName(imageAsset: 'assets/chocolate.jpg', name: "Name 2", score: 2000),
_buildName(imageAsset: 'assets/chocolate.jpg', name: "Name 3", score: 3000),
_buildName(imageAsset: 'assets/chocolate.jpg', name: "Name 4", score: 4000),
_buildName(imageAsset: 'assets/chocolate.jpg', name: "Name 5", score: 5000),
_buildName(imageAsset: 'assets/chocolate.jpg', name: "Name 6", score: 6000),
],
),
),
);
},
);
},
),
),
);
}
Widget _buildName({String imageAsset, String name, double score}) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: Column(
children: <Widget>[
SizedBox(height: 12),
Container(height: 2, color: Colors.redAccent),
SizedBox(height: 12),
Row(
children: <Widget>[
CircleAvatar(
backgroundImage: AssetImage(imageAsset),
radius: 30,
),
SizedBox(width: 12),
Text(name),
Spacer(),
Container(
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 20),
child: Text("${score}"),
decoration: BoxDecoration(
color: Colors.yellow[900],
borderRadius: BorderRadius.circular(20),
),
),
],
),
],
),
);
}