팝업처럼 위젯을 표시하는 방법
현재 저는 그리드 뷰가 있습니다. 탭하면 Hero 위젯을 사용하여 다른 페이지로 이동합니다.
이 페이지에는 해당 그리드 타일에 대한 정보를 표시하는 컨테이너가 있습니다.
내가 원하는 것은 해당 컨테이너가 다른 페이지가 아닌 그리드 뷰 위에 오도록하는 것입니다.
어떻게 그렇게 터뜨릴 수 있습니까? 가능하다면 영웅 애니메이션을 유지하고 싶습니다.
답변
다음과 같이 showDialog 메서드를 사용해야합니다.
InkWell(
child: GridItem(),
onTap: () {
showDialog(
context: context,
builder: (context) => AlertDialog(
content: Hero(child: Card(child: YourWidget()))
); // you can use SimpleDialog, specify barrier dismissible etc
},
)
다음은 대화 클래스에 대한 링크입니다. https://api.flutter.dev/flutter/material/Dialog-class.html
Hero에 대해 잘 모르겠습니다. 머리에서 쓰는 것처럼 작성했지만 트릭을 수행해야합니다 (ofc는 동일한 태그를 추가합니다. 위젯에 이미 카드가있는 경우 카드 부모가 필요하지 않습니다. Hero에는 Material 위젯이 필요합니다. )
나는 그것이 작동하기 때문에 내가 한 일을 게시하고 있습니다.
@Nonstapp 및 @Parth가 제안한 것은 PageRoutes에만 적용되므로 Hero 전환을 제외하고 작동합니다.
따라서 PageRoute를 사용하여 유사한 팝업을 표시하는 또 다른 방법을 찾았습니다.
내가 표시하고있는 정보 위젯 :
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: ...
패딩은 분명히 위치 지정을위한 것이며 Material 위젯은 IconButton과 같은 활성화 된 위젯과 Material 스타일을 부여하는 것입니다. Material 위젯에 투명한 색상을 지정합니다.
이것이 내가 그것을 부르는 방법입니다.
void seeDetails(BuildContext context, Book book) {
Navigator.push(
context,
PageRouteBuilder(
fullscreenDialog: true,
opaque: false,
pageBuilder: (_, __, ___) => ChangeNotifierProvider.value(
value: book,
child: DetailCard(),
),
),
);
}
PageRouter를 사용하여 전체 화면 대화 상자를 표시하지만 설정으로 인해 정보 카드 만 표시됩니다.
단점은 내가 다른 경로 atm에 있기 때문에 barrierDismissible을 활성화 할 수 없다는 것입니다.
이것은 내 결과입니다.
그러나 실제 해결책은 @pskink가 위에서 제안한 것입니다. 더 많은 설정과 조정이 필요하고 공급자에 문제가있었습니다. 구현 방법은 다음과 같습니다.
사용자 정의 대화 상자를 사용할 수 있습니다.
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),
),
),
],
),
],
),
);
}