I am trying to go back to another fragment, but the android studio keep saying that I cant override onBackPressed():
package com.educator.dualsignal
import android.os.Bundle
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
class DraftFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.draft_layout,null)
}
override fun onBackPressed() {
val fm = fragmentManager
fm!!.popBackStackImmediate()
}
}
onBackPressed() is a method in the Activity class. The Fragment class has no such method.
You need to implement your backstack logic in the parent Activity.
onBackPressed() is for activity, if you want to back pre fragment by clicking on back button you can add your fragments to a stack and when user tap on back button fragments pop.
https://medium.com/#bherbst/managing-the-fragment-back-stack-373e87e4ff62
Related
I am using fragments in my android application, when I run the program, the percentage name is displayed incorrectly, but after I switch to another fragment and perform some actions, everything becomes as it should be.
I set the title for the fragment on this line:
(activity as AppCompatActivity).supportActionBar?.title = "Soccer Quiz"
but it only applies when moving to another fragment.
My kotlin code:
package com.example.soccerquiz
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.navigation.Navigation
import com.example.soccerquiz.databinding.FragmentWelcomeScreenBinding
/**
* A simple [Fragment] subclass.
*/
class WelcomeScreenFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val binding: FragmentWelcomeScreenBinding =
DataBindingUtil.inflate(
inflater, R.layout.fragment_welcome_screen, container, false
)
binding.letsPlayButton.setOnClickListener { view: View ->
Navigation.findNavController(view)
.navigate(R.id.action_welcomeScreenFragment_to_quizFragment)
}
(activity as AppCompatActivity).supportActionBar?.title = "Soccer Quiz"
return binding.root
}
}
https://i.stack.imgur.com/LzNLk.png
https://i.stack.imgur.com/66NXk.png
Please help me with my problem.
It was necessary to change the title of fragment in navigation graph.
No need to install manually, because when you start the program it does not always work, you have to switch between fragments.
I've been doing this Android Studio course and I've stumbled upon a problem with this particular method. For whatever reason, I can use it in every fragment except one, in which apparently can't be imported.
Here is the fragment: (StartFragment)
package com.example.cupcake
import android.app.Fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.navigation.fragment.findNavController
import com.example.cupcake.databinding.FragmentStartBinding
/**
* This is the first screen of the Cupcake app. The user can choose how many cupcakes to order.
*/
class StartFragment : Fragment() {
// Binding object instance corresponding to the fragment_start.xml layout
// This property is non-null between the onCreateView() and onDestroyView() lifecycle callbacks,
// when the view hierarchy is attached to the fragment.
private var binding: FragmentStartBinding? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val fragmentBinding = FragmentStartBinding.inflate(inflater, container, false)
binding = fragmentBinding
return fragmentBinding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding?.apply {
// Set up the button click listeners
orderOneCupcake.setOnClickListener { orderCupcake(1) }
orderSixCupcakes.setOnClickListener { orderCupcake(6) }
orderTwelveCupcakes.setOnClickListener { orderCupcake(12) }
}
}
/**
* Start an order with the desired quantity of cupcakes and navigate to the next screen.
*/
fun orderCupcake(quantity: Int) {
findNavController().navigate(R.id.action_startFragment_to_flavorFragment) //here is the error
}
/**
* This fragment lifecycle method is called when the view hierarchy associated with the fragment
* is being removed. As a result, clear out the binding object.
*/
override fun onDestroyView() {
super.onDestroyView()
binding = null
}
}
The whole code is in the code link, thanks
Your fragment extends android.app.Fragment - that's the deprecated, should never be used framework fragment. You need to replace your import android.app.Fragment with import androidx.fragment.app.Fragment to actually extend the AndroidX Fragment you need to use with Navigation.
I'm new to Kotlin/Android development and I'm making an app to display quizzes. Recently I decided to begin using fragments. On my MainActivity which has three fragments, I'd like one to have a method of clicking a subject and being taken to that particular quiz activity.
Note, there is only one quiz activity, but the intents pass a variable to display the relevant data for the quiz.
I had correctly implemented this when this page was not a fragment but struggling to find a solution this time.
Subject Fragment:
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.financialapp.InformationPage
import com.example.financialapp.databinding.FragmentModuleBinding
import android.content.Intent
class ModuleFragment : Fragment(com.quizapp.R.layout.fragment_module) {
private var _binding: FragmentModuleBinding ? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentModuleBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val subjectOne = binding.tvEnglish
subjectOne.setOnClickListener {
sendIntent(0)
}
val subjectTwo = binding.tvGeography
subjectOne.setOnClickListener {
sendIntent(1)
}
val subjectThree = binding.tvHistory
subjectThree.setOnClickListener{
sendIntent(2)
}
...
}
private fun sendIntent(passedVariable: Int) {
val intent = Intent(this, SubjectPage::class.java)
intent.putExtra("subject", passedVariable)
startActivity(intent)
finish()
}
...
At present I have errors from Intent asking to create a function, same with finish().
Having looked through several tutorials I can't seem to see whether it's possible or not.
finish() is actually called on activity so you can use requireActivity() get hold of the hosting activity of your fragment & instead of using this in Intent params you can use requireContext()
Example:
private fun sendIntent(passedVariable: Int) {
val intent = Intent(requireContext(), MainActivity::class.java)
intent.putExtra("subject", passedVariable)
startActivity(intent)
requireActivity().finish()
}
Actually, as you started to use fragments you can avoid to start another activity.
Use childFragmentManager and just create for your quiz another fragment.
https://developer.android.com/reference/androidx/fragment/app/Fragment#getChildFragmentManager()
I have three tabs (fragments) in my app, one of which should be a settings tab. I would like to use the AndroidX preference library for this settings tab.
I can open the settings tab and change settings, however once I have opened the settings tab once, the bottom navigation bar does not work anymore. When I close and restart the app the preferences have been saved. I think this is because .replace(android.R.id.content, SettingsFragmentCompat()) replaces the entire activity including the bottom navigation bar.
How can I correctly load the preference fragment into the tab fragment?
SettingsFragment.kt (tab fragment)
package net.htlgrieskirchen.jheschl17.hypernote.ui.settings
import android.app.Activity
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import net.htlgrieskirchen.jheschl17.hypernote.R
class SettingsFragment : Fragment() {
private lateinit var view1: View
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
view1 = inflater.inflate(R.layout.fragment_settings, container, false)
requireActivity().supportFragmentManager
.beginTransaction()
.replace(android.R.id.content, SettingsFragmentCompat())
.commit()
return view1
}
}
SettingsFragmentCompat.kt (android boilerplate)
package net.htlgrieskirchen.jheschl17.hypernote.ui.settings
import android.os.Bundle
import androidx.preference.PreferenceFragmentCompat
import net.htlgrieskirchen.jheschl17.hypernote.R
class SettingsFragmentCompat : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.preferences, rootKey)
}
}
I solved the issue by changing the root element of the layout file corresponding to SettingsFragment to androidx.drawerlayout.widget.DrawerLayout with id view_settings and changing .replace(android.R.id.content, SettingsFragmentCompat()) to .replace(R.id.view_settings, SettingsFragmentCompat()).
I am trying to get a button to work correctly when it is clicked. for basic example I am using a chronometer. Using Android Studio 3.4.2, I can uses this code in a Basic Activity project in the Main Activity and it works fine. the same code does not work using a Tabbed Activity when I put it in the fragment, fragment page holder or main activity for my Tabbed Activity.
Main Activity of Basic Activity
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity;
import android.view.Menu
import android.view.MenuItem
import android.view.View
import kotlinx.android.synthetic.main.activity_main.*
mport kotlinx.android.synthetic.main.content_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
val chronometer = chronometer
val btnstart = (Button)rootView.findViewById(R.id.btnstart);
btnstart.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View) {
chronometer.start()
}
})
}
Fragment of Tabbed Activity (no matter where i put it, it does not work)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_retention, container, false)
}
This is the Debug error i keep getting:
PID: 5241
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
}
the suggestions here do not seems to give me any positive results either
onClickListener doesnt work in Tabbed Activity Android
that did the trick. thank you. I placed this in the fragment under inflater as:
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_bph, container, false)}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val chronometer = chronometer
btnstart.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View) {
chronometer.start()