Issue
I'm making an app with two fragments, which are home-fragment and youtube-fragment. When I press the "search" button, I can get to youtube-fragment properly. However, when I press the back button(the back on my phone instead of the back arrow in the toolbar), I just exit the app without getting any error or warning. I would like to get back to the home-fragment after press the back button.
Here is my code of both fragments:
homeFragment
package com.example.signlanguage_new
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.GridLayout
import android.widget.Toast
import android.widget.Toast.LENGTH_SHORT
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.GridLayoutManager
import com.example.signlanguage_new.databinding.FragmentHomeBinding
class HomeFragment : Fragment() {
private val viewModel: MyViewModel by activityViewModels {
MyViewModelFactory(
(activity?.application as SignLanguageApplication).database.VideoDao()
)
}
private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentHomeBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
viewModel.result.observe(viewLifecycleOwner)
{
if(it==null) {
Toast.makeText(requireContext(), "查無資料", LENGTH_SHORT).show()
}
else
{
val action=HomeFragmentDirections.actionHomeFragmentToYoutubeFragment()
findNavController().navigate(action)
}
}
super.onViewCreated(view, savedInstanceState)
binding.apply {
searchBtn.setOnClickListener {
val search=binding.search.text.toString()
if(search=="")
{
Toast.makeText(requireContext(), "請輸入關鍵字", LENGTH_SHORT).show()
}
else
{
viewModel.searchVideo(search)
}
}
}
val adapter=homeButtonAdapter{
viewModel.category(it)
}
binding.recyclerView.adapter=adapter
binding.recyclerView.layoutManager=GridLayoutManager(this.context,2)
}
}
youtubeFragment
package com.example.signlanguage_new
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.OnBackPressedCallback
import androidx.activity.addCallback
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.signlanguage_new.data.Video
import com.example.signlanguage_new.databinding.FragmentYoutubeBinding
class youtubeFragment : Fragment() {
private val viewModel: MyViewModel by activityViewModels {
MyViewModelFactory(
(activity?.application as SignLanguageApplication).database.VideoDao()
)
}
private var _binding: FragmentYoutubeBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentYoutubeBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val Dataset= viewModel.result.value
binding.recyclerView.adapter= Dataset?.let {
VideoAdapter(requireContext(),
it,this.lifecycle)
}
binding.recyclerView.layoutManager = LinearLayoutManager(this.context)
}
}
And here is the nav_graph and my mainActivity:
nav_graph
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/homeFragment">
<fragment
android:id="@+id/homeFragment"
android:name="com.example.signlanguage_new.HomeFragment"
android:label="fragment_home"
tools:layout="@layout/fragment_home" >
<action
android:id="@+id/action_homeFragment_to_youtubeFragment"
app:destination="@id/youtubeFragment"
app:popUpTo="@id/homeFragment"
app:popUpToInclusive="true" />
</fragment>
<fragment
android:id="@+id/youtubeFragment"
android:name="com.example.signlanguage_new.youtubeFragment"
android:label="fragment_youtube"
tools:layout="@layout/fragment_youtube" />
</navigation>
MainActivity
package com.example.signlanguage_new
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.KeyEvent
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.NavigationUI.setupActionBarWithNavController
class MainActivity : AppCompatActivity(R.layout.activity_main) {
private lateinit var navController: NavController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Retrieve NavController from the NavHostFragment
val navHostFragment = supportFragmentManager
.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
navController = navHostFragment.navController
// Set up the action bar for use with the NavController
setupActionBarWithNavController(this, navController)
}
/**
* Handle navigation when the user chooses Up from the action bar.
*/
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp() || super.onSupportNavigateUp()
}
}
I guess it may have something to do with my adapter for the recyclerview in youtube-fragment because I provide the lifecycle as a parameter for it.
Here it is:
VideoAdapter
package com.example.signlanguage_new
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.example.signlanguage_new.data.Video
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.AbstractYouTubePlayerListener
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
class VideoAdapter (private val context: Context, private val dataset:List<Video>, private val lifecycle: Lifecycle) :RecyclerView.Adapter<VideoAdapter.ItemViewHolder>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
val youTubePlayerView: YouTubePlayerView = LayoutInflater.from(parent.context).inflate(R.layout.videolistitem,parent,false) as YouTubePlayerView
lifecycle.addObserver(youTubePlayerView)
return ItemViewHolder(youTubePlayerView)
}
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
val current=dataset[position]
holder.setIsRecyclable(false)
holder.loadVideo(current.ytId)
}
override fun getItemCount(): Int {
return dataset.size
}
class ItemViewHolder(playerView: YouTubePlayerView) :
RecyclerView.ViewHolder(playerView) {
val youTubePlayerView: YouTubePlayerView = playerView
var youTubePlayer: YouTubePlayer? = null
var currentVideoId: String? = null
fun loadVideo(videoId: String?) {
currentVideoId = videoId
if (youTubePlayer == null) return
if (videoId != null) {
youTubePlayer!!.cueVideo(videoId, 0F)
}
}
init {
youTubePlayerView.addYouTubePlayerListener(object : AbstractYouTubePlayerListener() {
override fun onReady(initializedYouTubePlayer: YouTubePlayer) {
youTubePlayer = initializedYouTubePlayer
currentVideoId?.let {
youTubePlayer!!.cueVideo(it, 0F)
}
}
})
}
}
}
Does anyone know how I can get to the home fragment instead of leaving the app?
Solution
When you add app:popUpTo="@id/homeFragment", app:popUpToInclusive="true"
to your navigation action, this means you want to remove the homeFragment
from back stack. essentially meaning when you press back, homeFragment
will no longer be there, if you want back button to take you to homeFragment
, you need to update the action as
<action
android:id="@+id/action_homeFragment_to_youtubeFragment"
app:destination="@id/youtubeFragment" />
Answered By - mightyWOZ
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.