팝업처럼 위젯을 표시하는 방법

Sep 22 2020

현재 저는 그리드 뷰가 있습니다. 탭하면 Hero 위젯을 사용하여 다른 페이지로 이동합니다.

이 페이지에는 해당 그리드 타일에 대한 정보를 표시하는 컨테이너가 있습니다.

내가 원하는 것은 해당 컨테이너가 다른 페이지가 아닌 그리드 뷰 위에 오도록하는 것입니다.

어떻게 그렇게 터뜨릴 수 있습니까? 가능하다면 영웅 애니메이션을 유지하고 싶습니다.

답변

1 Nonstapp Sep 22 2020 at 15:34

다음과 같이 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 위젯이 필요합니다. )

1 Eren Sep 22 2020 at 17:41

나는 그것이 작동하기 때문에 내가 한 일을 게시하고 있습니다.

@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가 위에서 제안한 것입니다. 더 많은 설정과 조정이 필요하고 공급자에 문제가있었습니다. 구현 방법은 다음과 같습니다.

ParthPitroda Sep 22 2020 at 15:23

사용자 정의 대화 상자를 사용할 수 있습니다.

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),
                  ),
                ),
              ],
            ),
          ],
        ),
      );
    }