如何在Android中通过Fragment实现点击歌曲后的全屏播放界面?
Hey there! Let's get that full-screen Now Playing Fragment up and running when a song is tapped. Here's a straightforward, step-by-step guide that fits right into your existing setup:
First, we'll build the fragment that holds your full-screen playback UI.
1.1 Make the Fragment Layout (res/layout/now_playing_fragment.xml)
This layout will fill the entire screen and include all your playback elements (album art, song title, controls, etc.):
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#121212"> <!-- Dark background for playback vibe --> <!-- Album Art --> <ImageView android:id="@+id/album_art" android:layout_width="match_parent" android:layout_height="300dp" android:scaleType="centerCrop" android:src="@drawable/album_placeholder" app:layout_constraintTop_toTopOf="parent"/> <!-- Song Title --> <TextView android:id="@+id/song_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#FFFFFF" android:textSize="24sp" android:layout_marginTop="16dp" app:layout_constraintTop_toBottomOf="@id/album_art" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"/> <!-- Back Button (to return to song list) --> <ImageView android:id="@+id/back_btn" android:layout_width="48dp" android:layout_height="48dp" android:src="@drawable/ic_back" android:layout_margin="16dp" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"/> <!-- Add more playback controls (play/pause, skip, etc.) here --> </androidx.constraintlayout.widget.ConstraintLayout>
1.2 Create the Fragment Class
Use this to handle full-screen logic and receive song data from your main activity (example in Kotlin; Java version follows the same logic):
import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.view.WindowManager import androidx.fragment.app.Fragment class NowPlayingFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.now_playing_fragment, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // Enable full-screen mode (hide status and navigation bars) activity?.window?.apply { setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN ) decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY } // Receive song data passed from MainActivity arguments?.let { bundle -> val songTitle = bundle.getString("SONG_TITLE") val albumArtResId = bundle.getInt("ALBUM_ART_RES_ID") // Update UI with song details view.findViewById<TextView>(R.id.song_title).text = songTitle view.findViewById<ImageView>(R.id.album_art).setImageResource(albumArtResId) } // Handle back button click to return to song list view.findViewById<ImageView>(R.id.back_btn).setOnClickListener { parentFragmentManager.popBackStack() } } override fun onDestroyView() { super.onDestroyView() // Restore status bar when fragment is closed activity?.window?.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN) } companion object { // Helper method to create fragment with song data fun newInstance(songTitle: String, albumArtResId: Int): NowPlayingFragment { val fragment = NowPlayingFragment() val args = Bundle().apply { putString("SONG_TITLE", songTitle) putInt("ALBUM_ART_RES_ID", albumArtResId) } fragment.arguments = args return fragment } } }
Your existing main_activity.xml (RelativeLayout) needs a container to hold the fragment. Add this FrameLayout as a sibling to your song list:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- Your existing song list (RecyclerView/ListView) --> <RecyclerView android:id="@+id/song_recycler" android:layout_width="match_parent" android:layout_height="match_parent"/> <!-- Fragment container (hidden by default) --> <FrameLayout android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="gone"/> </RelativeLayout>
In your MainActivity, update the song list item click listener to launch the full-screen fragment:
// Example with RecyclerView val songRecycler = findViewById<RecyclerView>(R.id.song_recycler) songRecycler.adapter = SongAdapter(songList) { selectedSong -> // Create fragment with selected song data val nowPlayingFragment = NowPlayingFragment.newInstance( selectedSong.title, selectedSong.albumArtResId ) // Replace container with fragment and add to back stack supportFragmentManager.beginTransaction() .replace(R.id.fragment_container, nowPlayingFragment) .addToBackStack(null) // Allows back button to return to list .commit() // Show the fragment container findViewById<FrameLayout>(R.id.fragment_container).visibility = View.VISIBLE }
- Add Transition Animations: Make the fragment slide up from the bottom for a smoother feel. Create animation files in
res/anim/and add them to the transaction:supportFragmentManager.beginTransaction() .setCustomAnimations( R.anim.slide_up, R.anim.fade_out, R.anim.fade_in, R.anim.slide_down ) .replace(R.id.fragment_container, nowPlayingFragment) .addToBackStack(null) .commit() - Use Single-Activity Architecture: For cleaner code, consider making your song list a fragment too, so you can swap between list and playback fragments seamlessly.
内容的提问来源于stack exchange,提问作者Ashuthosh Patoa

