Is there a way to refresh a fragment in the onResume method? - kotlin

My favourites fragment does not display the data given correctly unless the onCreateView function is called. This means that the fragment needs to be deleted and created again. Is there a way to appropriately refresh the fragment in the onResume method?
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val fragment = this
_binding = FragmentFavouritesBinding.inflate(layoutInflater)
binding.recyclerView.apply{
layoutManager = GridLayoutManager(activity,2)
adapter= CardAdapter(favouriteList, fragment)
}
return binding.root
}
override fun onResume() {
super.onResume()
orderFavourites()
sortFavourites()
if(favouriteList.isEmpty()){
Toast.makeText(this.context,"No Favourites Found", Toast.LENGTH_SHORT).show()
}
else{
Toast.makeText(this.context,"resumed", Toast.LENGTH_SHORT).show()
}
}
The favouriteList is updated in another activity and I have ensured that it contains the correct values. It displays as intended after deleting and creating the fragment once more.

Related

Activities vs Fragments for apps

I have been trying to figure this out for a bit now. I see a lot of developers and youtubers (tutorials) saying that we should use as little activities as possible in order for a faster, more efficient and less resource heavy code/app. I was wondering if there is a way to create a Log-in and Sign-up using only the MainActivity for both Log-in and Sign-Up in combination with fragments for navigation between them.
Or
Do we need atleast 2 or more activities to handle that process ( Log-in & Sign-Up )?
Example: 1 activity for log-in and 1 activity for sign-up.
Appreciate and welcome any answers regarding this topic!
Theoretically, you could have your entire application run on a single Activity and use Fragments for all of the pages.
Each fragment has its own lifecycle within the activity.
MainActivity can look like this
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
loadFragment(2)
}
public fun loadFragment(page: Int){
if(page == 1){
// load login
val manager = supportFragmentManager.beginTransaction()
manager.replace(R.id.fragment_holder, LoginFragment()).commit()
}else{
// load register
val manager = supportFragmentManager.beginTransaction()
manager.replace(R.id.fragment_holder, LoginFragment()).commit()
}
}
}
LoginFragment can look like this
class LoginFragment : Fragment() {
lateinit var myButton: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_login, container, false)
myButton = view.findViewById(R.id.my_button)
myButton.apply {
setOnClickListener { toRegister() }
}
return view;
}
fun toRegister(){
// replace the fragment in main activity with register fragment
(requireActivity() as MainActivity).loadFragment(1)
}
}
RegisterFragment can look like this
class RegisterFragment : Fragment() {
lateinit var mButton: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_register, container, false)
mButton = view.findViewById(R.id.my_button)
mButton.apply {
setOnClickListener { toLogin() }
}
return view;
}
fun toLogin(){
// replacing the fragment in the main activity with the login fragment
(requireActivity() as MainActivity).loadFragment(1)
}
}
Basically, we replace the fragment displayed in the activity by calling loadfragment.
This logic can be applied to as many fragments as is necessary.

How to retain EditText values between fragments

I am a novice in Android development. I am currently working in fragments. So basically I am having two fragments each have their own Edittext and buttons. On back press between fragments works fine but when using the button to move to the next fragment the second fragment fails to hold the edit text value. I tried OnSavedInstance it doesn't help me.
FirstFragment.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_first, container, false)
view.findViewById<Button>(R.id.btn1).setOnClickListener {
ediText1 = view.findViewById<EditText>(R.id.et1).text.toString()
Toast.makeText(activity?.baseContext,ediText1,Toast.LENGTH_SHORT).show()
Navigation.findNavController(view).navigate(R.id.action_firstFragment_to_secondFragment)
}
return view
}
SecondFragment.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_second, container, false)
view.findViewById<Button>(R.id.btn2).setOnClickListener {
ediText2 = view.findViewById<EditText>(R.id.et2).text.toString()
Toast.makeText(activity?.baseContext,ediText2, Toast.LENGTH_SHORT).show()
Navigation.findNavController(view).navigate(R.id.action_secondFragment_to_thirdFragment) }
return view
}
There are many ways to retain the values, most easy is to use ViewModel , since you are using Navigation Components , ViewModel can be scoped to navGraph , see this

why onClickListener does not work in my fragment activity?

Im new in programming, and i got stuck with adding onClickListener in my FragmentHome.kt
i added this code to my existing activity:
val exc = this.findViewById<Button>(R.id.execute)
exc.setOnClickListener {
Toast.makeText(this, "You clicked me.", Toast.LENGTH_SHORT).show()
}
I tried set onClicklistener on a blank activity and it worked, but when i added it to an existing
Fragment activity it does nothing (it should display a toast with some text)
I see no error messages so i don't know where the problem could be.
Thank you for your responses.
enter code here
public class FragmentHome : Fragment() {
public class HomeFragmentElements : AppCompatActivity() {
private lateinit var spinView: Spinner
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.fragment_home)
val exc = this.findViewById<Button>(R.id.execute)
exc.setOnClickListener {
Toast.makeText(this, "You clicked me.", Toast.LENGTH_SHORT).show()
}
spinView = findViewById(R.id.spinner)
spinView.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(
parent: AdapterView<*>?,
view: View?,
position: Int,
id: Long
) {
TODO("Not yet implemented")
}
override fun onNothingSelected(parent: AdapterView<*>?) {
TODO("Not yet implemented")
}
}
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home, container, false)
}
}
enter code here
Try to put your code into "onViewCreated":
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val exc = this.findViewById<Button>(R.id.execute)
exc.setOnClickListener {
Toast.makeText(this, "You clicked me.", Toast.LENGTH_SHORT).show()
}
}
onViewCreated is executed after "onCreateView". View bindings and initializations should be into onViewCreated
change the following in your onCreateView
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view: View = inflater.inflate(R.layout.fragment_home, container, false)
collectId(view)
return view
}
fun collectId(view: view){
val exc = view.findViewById<Button>(R.id.execute)
exc.setOnClickListener {
Toast.makeText(this, "You clicked me.", Toast.LENGTH_SHORT).show()
}
}
You can consider viewBinding instead of findViewById
It looks like you have defined an AppCompatActivity subclass inside your Fragment class's definition, kind of like this:
class MyFragment: Fragment {
class MyActivity: AppCompatActivity() {
//...
}
}
The ability to define a non-inner class in a nested way is purely a code organization tool. There is absolutely no connection between your Fragment and Activity classes here. The code above is no different than if you did this, with each class in a completely different file:
class MyFragment: Fragment {
}
class MyActivity: AppCompatActivity() {
}
It also doesn't make sense to think of an Activity as a child of a Fragment. A Fragment is a piece of an Activity, so it's the other way around.
All the code that you have in this Activity's onCreate should be put in the Fragment's onViewCreated() function, except for the call to setContentView(), because that's what your overriding of onCreateView() does. And remove the unused nested Activity class.
Also, you don't need to override onCreateView if you're simply inflating a layout and returning it. You can put the layout directly in the super-constructor call like this:
public class FragmentHome : Fragment(R.layout.fragment_home) {
private lateinit var spinView: Spinner
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// your view setup code
}
}

How do I add an actionbar menu in my fragment using Kotlin

How do I add an actionbar menu in my fragments using Kotlin? When I run the code below nothing shows up.
class Fragment1: Fragment() {
private lateinit var fview: View
override fun onCreateView(
inflater: LayoutInflater,container: ViewGroup?,
savedInstanceState: Bundle?
): View?{
// Inflate the layout for this fragment
dissview = inflater.inflate(R.layout.fragment_dissability, container, false)
setHasOptionsMenu(true)
return fview
}//end on create
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.mainmenu, menu);
super.onCreateOptionsMenu(menu, inflater)
}

no event OnClickListener in fragment button kotlin

I am working kotlin. I have a fragment on my Activity . l want when click on button inside of fragment activity go to another activity .
this code my used in fragment class
class fragment_Arr :Fragment(), View.OnClickListener {
override fun onClick(v: View?) {
val intent = Intent(activity, FlightDeatilasDep::class.java)
startActivity(intent)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_arrivel,container,false)
loadmorefilghtsbeforday.setOnClickListener{this}
}
}
when l debug app and click on button no event happening !
loadmorefilghtsbeforday.setOnClickListener{} body of the lambda is empty - nothing happen.
Please register your listener by
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_arrivel,container,false)
loadmorefilghtsbeforday.setOnClickListener(this)
return view
}
or if you prefer using lambdas
loadmorefilghtsbeforday.setOnClickListener{ onClick(null) } could be called but then your fragment don't need to implements View.OnClickListener.
and class names in Kotlin/java should start from capital later: FragmentArr.
_ is not recommended