วิธีแสดงวิดเจ็ตเช่นป๊อปอัป

Sep 22 2020

ขณะนี้ฉันมีมุมมองแบบตาราง เมื่อฉันแตะมันฉันจะไปที่หน้าอื่นโดยใช้วิดเจ็ตฮีโร่

ในหน้านั้นฉันมีเพียงคอนเทนเนอร์ที่แสดงข้อมูลเกี่ยวกับไทล์กริดนั้น

สิ่งที่ฉันต้องการคือให้คอนเทนเนอร์นั้นมาอยู่ด้านบนของมุมมองกริดแทนที่จะเป็นเพจอื่น

โผล่มาแบบนั้นได้ยังไง และถ้าเป็นไปได้ฉันควรเก็บแอนิเมชันของฮีโร่ไว้

คำตอบ

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

เกี่ยวกับฮีโร่ฉันไม่แน่ใจเพราะฉันเขียนเหมือนจากส่วนหัว แต่มันควรทำเคล็ดลับ (ofc ต่อท้ายแท็กเดียวกันคุณไม่จำเป็นต้องใช้การ์ดพาเรนต์หากวิดเจ็ตของคุณมีวิดเจ็ตอยู่แล้ว - ฮีโร่ต้องการวิดเจ็ต Material )

1 Eren Sep 22 2020 at 17:41

ฉันโพสต์สิ่งที่ฉันทำลงไปเพราะมันได้ผล

สิ่งที่ @Nonstapp และ @Parth แนะนำให้ใช้งานได้ยกเว้นการเปลี่ยนฮีโร่เนื่องจากใช้กับ PageRoutes เท่านั้น

ดังนั้นฉันจึงพบวิธีอื่นในการแสดงป๊อปอัปที่คล้ายกันกับ 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 คือการให้สไตล์ Material และวิดเจ็ตที่เปิดใช้งานเช่น IconButton ให้วิดเจ็ต Material เป็นสีโปร่งใส

นี่คือวิธีที่ฉันเรียกมันว่า:

void seeDetails(BuildContext context, Book book) {
    Navigator.push(
      context,
      PageRouteBuilder(
        fullscreenDialog: true,
        opaque: false,
        pageBuilder: (_, __, ___) => ChangeNotifierProvider.value(
          value: book,
          child: DetailCard(),
        ),
      ),
    );
  }

ฉันใช้ PageRouter เพื่อแสดงกล่องโต้ตอบแบบเต็มหน้าจอ แต่เนื่องจากการตั้งค่าของฉันอยู่ที่นั่นจึงมองเห็นเฉพาะการ์ดข้อมูลเท่านั้น

ข้อเสียคือฉันไม่สามารถเปิดใช้งานสิ่งกีดขวางได้

นี่คือผลลัพธ์ของฉัน:

อย่างไรก็ตามวิธีแก้ปัญหาที่แท้จริงคือสิ่งที่ @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),
                  ),
                ),
              ],
            ),
          ],
        ),
      );
    }