用户单击列表视图项后如何制作包含音频的详细屏幕

How to make detailed screen that has audio in it after user clicked on the listview item

如何制作每个屏幕都有音频的详细信息屏幕。我是否必须为每个列表视图项目的每个音频播放器声明?任何人都可以给我一些见解以使其尽可能简单吗?顺便说一句,我使用 just_audio 插件。预先感谢任何可以帮助我的人:)

//声明

late AudioPlayer player;
late AudioPlayer player2;

  @override
  void initState() {
    super.initState();
    player = AudioPlayer();
    player2 = AudioPlayer();
  }

  @override
  void dispose() {
    player.dispose();
    player2.dispose();
    super.dispose();
  }

//我打算在每个列表视图项目的详细屏幕中放置的音频播放器按钮

FlatButton(
                onPressed: () async {
                  try {
                    await player.setAsset("assets/audio/mim dengung.mp3");
                    player.play();
                  } on PlayerException catch (e) {
                    print("Error code: ${e.code}");
                    print("Error message: ${e.message}");
                  } on PlayerInterruptedException catch (e) {
                    print("Connection aborted: ${e.message}");
                  } catch (e) {
                    print(e);
                  }
                },
                padding: EdgeInsets.symmetric(horizontal: 50),
                shape: StadiumBorder(
                    side: BorderSide(color: Colors.white54, width: 2)),
                child: Container(
                  width: 80,
                  height: 50,
                  padding:
                      EdgeInsets.symmetric(vertical: 3, horizontal: 10),
                  decoration: ShapeDecoration(
                    color: Colors.amber,
                    shape: StadiumBorder(),
                  ),
                  child: Row(
                    children: <Widget>[
                      Icon(Icons.volume_up_outlined),
                      Text(
                        " م ",
                        style:
                            TextStyle(color: Colors.black87, fontSize: 25),
                        textAlign: TextAlign.center,
                      ),
                    ],
                  ),
                ),
              ),

这是列表视图项,如果用户单击任何列表视图项,它将在其中显示详细信息屏幕(下面的代码)

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';

import '../../constants.dart';
import 'detail_screen.dart';
import 'model.dart';

class Basic extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<Basic> {
  List<Item> _itemList = [
    Item(
        title: "Hamzah Wasal",
        longText:
            "Hamzah Wasal adalah hamzah zaidah (tambahan) yang berada pada awal. Ia harus diucapkan jika berada di awal kalimah dan tidak diucapkan jika disambung dengan ayat sebelumnya.\n\nHamzah Wasal dibaca Dhommah(baris depan) apabila huruf ketiga adalah Dhommah. Jika huruf ketiga adalah Fathah (baris atas) atau Kasrah (baris bawah), ia perlu dibaca dengan Kasrah.",
        image: "assets/images/hamzah_wasal.jpg"),
    Item(
        title: "Ghunnah",
        longText:
            "Dari segi bahasa ia bermaksud suara yang keluar dari pangkal rongga hidung.\n\nDari segi istilah ia bermaksud suara yang indah dan teratur pada huruf nun(termasukk tanwin) dan mim.\n\nDalam keadaan normal, makhraj mim adalah dua bibir bertemu dan makhraj nun adalah hujung lidah bertemu lelangit mulut. Tetapi dalam keadaan ghunnah, makhraj mim dan nun bercampur dengan khaisyum (baca lebih lanjut dalam bahagian makhraj).",
        image: "assets/images/hamzah_wasal.jpg"),
    Item(
        title: "Sukun",
        longText:
            "Terdapat 2 jenis sukun (mati) di dalam Al Quran. Sukun yg pertama dinamakan Sukun Asli manakala yg kedua adalah Sukun yg mendatang.\n\nSukun Asli adalah huruf yg bertanda sukun. Sukun itu dibaca sama ada ketika waqaf (berhenti) mahupun ketika wasal (sambung). Dinamakan Asli kerana ia tidak berubah dan merupakan asal kepada huruf tersebut bertanda sukun.\n\nContoh hukum adalah pada Mad Lazim Kalimi.\n\nSukun mendatang pula atau disebut ‘aridhah adalah sukun yg terhasil daripada huruf yg bertanda (baris, sabdu atau tanwin). Disebut sukun mendatang adalah disebabkan berlaku sesuatu pada huruf berbaris tersebut iaitu waqaf (berhenti). Ia menjadi sukun apabila waqaf tetapi kembali kepada bacaan asalnya berbaris apabila wasal (sambung).\n\nContohnya adalah pada hukum Mad Aridh Lissukun.",
        image: "assets/images/hamzah_wasal.jpg"),
    Item(
        title: "Mad Ta’zhim",
        longText:
            "Mad Ta’zhim ialah mad pada perkataan لآ bererti “tidak” ketika pertemuannya dengan perkataan yang terdapat pada kalimah tauhid (إله).\n\n Bagi mereka yang membaca mad jaiz munfasil dengan kadar 2/4/6 harakat, apabila bertemu perkataan (إله) di dalam kalimah tauhid, ia dibaca 6 harakat.",
        image: "assets/images/mad silah qasirah.jpg"),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: primaryColor,
        appBar: AppBar(
          title: const Text("Asas"),
          centerTitle: true,
          backgroundColor: secondaryColor,
        ),
        body: Center(
            child: ListView.builder(
          itemCount: _itemList.length,
          itemBuilder: (context, index) {
            return GestureDetector(
                onTap: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                        builder: (context) =>
                            DetailScreen(item: _itemList[index])),
                  );
                },
                child: Card(
                  color: Colors.white,
                  child: Container(
                    margin: EdgeInsets.all(18),
                    child: Text(
                      _itemList[index].title,
                      style: TextStyle(
                        fontSize: 19,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ),
                ));
          },
        )));
  }
}

这是用户点击任何列表视图项目后出现的详细屏幕

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../../constants.dart';
import 'model.dart';

class DetailScreen extends StatelessWidget {
  final Item item;
  const DetailScreen({Key? key, required this.item}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: secondaryColor,
      ),
      body: Center(
        child: SingleChildScrollView(
          scrollDirection: Axis.vertical,
          child: Padding(
            padding: const EdgeInsets.all(30),
            child: Column(children: [
              Padding(
                padding: const EdgeInsets.only(bottom: 20),
                child: Text(
                  item.title,
                  style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
                ),
              ),
              Padding(
                padding: const EdgeInsets.only(bottom: 20),
                child: Text(
                  item.longText,
                  style: TextStyle(fontSize: 18.5),
                  textAlign: TextAlign.justify,
                ),
              ),
              SizedBox(height: 100, child: Image.asset(item.image)),
            ]),
          ),
        ),
      ),
    );
  }
}

//这是我添加音频播放逻辑后出现的错误。 Idk 在 DetailScreen 中声明音频播放器的位置 class

您已经在 Item 中将 titlelongTextimage 传递给您的 DetailScreen。因此,您也可以将 audio 添加到 Item 并在 DetailScreen 中访问它。然后你可以将音频播放器逻辑移动到你的 DetailScreen 并且只使用一个音频播放器来播放基于 item.audio.

的音频

更新

DetailScreen代码:

class DetailScreen extends StatefulWidget {
  final Item item;
  const DetailScreen({Key? key, required this.item}) : super(key: key);

  @override
  State<DetailScreen> createState() => _DetailScreenState();
}

class _DetailScreenState extends State<DetailScreen> {
  final _player = AudioPlayer();

  @override
  void initState() {
    super.initState();
    _init();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: secondaryColor,
      ),
      body: Center(
        child: SingleChildScrollView(
          scrollDirection: Axis.vertical,
          child: Padding(
            padding: const EdgeInsets.all(30),
            child: Column(
              children: [
                Padding(
                  padding: const EdgeInsets.only(bottom: 20),
                  child: Text(
                    widget.item.title,
                    style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.only(bottom: 20),
                  child: Text(
                    widget.item.longText,
                    style: TextStyle(fontSize: 18.5),
                    textAlign: TextAlign.justify,
                  ),
                ),
                SizedBox(
                  height: 100,
                  child: Image.asset(widget.item.image),
                ),
                SizedBox(height: 16),
                FlatButton(
                  onPressed: _player.play,
                  padding: EdgeInsets.symmetric(horizontal: 50),
                  shape: StadiumBorder(side: BorderSide(color: Colors.white54, width: 2)),
                  child: Container(
                    width: 80,
                    height: 50,
                    padding: EdgeInsets.symmetric(vertical: 3, horizontal: 10),
                    decoration: ShapeDecoration(
                      color: Colors.amber,
                      shape: StadiumBorder(),
                    ),
                    child: Row(
                      children: <Widget>[
                        Icon(Icons.volume_up_outlined),
                        Text(
                          " م ",
                          style: TextStyle(color: Colors.black87, fontSize: 25),
                          textAlign: TextAlign.center,
                        ),
                      ],
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    _player.dispose();
    super.dispose();
  }

  Future<void> _init() async {
    _player.playbackEventStream.listen((event) {}, onError: (Object e, StackTrace stackTrace) {
      print('A stream error occurred: $e');
    });
    try {
      await _player.setAsset("assets/audio/mim dengung.mp3");
    } catch (e) {
      print("Error loading audio source: $e");
    }
  }
}