问题
What I would like to do
I would like to call Activity from Fragment to realize both transitions among fragments and activities simultaneously in an Android app.
I have succeeded to call one specific method on activity file from fragment file, but I have trouble with calling an entire activity from a fragment.
SampleFragment - MainActivity's fragmentMethod() is called once the button is clicked on the page
Sample1Fragment - FormActivity is called once the button is clicked on the page
FormActivity - FormActivity2 is called once the button is clicked on the page
The above is same as my former question: How can I fix the code to call Activity from Fragment in Android App?
Errors and Problems
It was succeeded to build a project and run the app on the emulator. However, the screen was suddenly shut down when I click the button to call FormActivity on Sample1Fragment.
I have trouble with fix this problem.
Error Message to the below part on Sample1Fragment.kt
Modifier 'override' is not applicable to 'local function'
Sample1Fragment.kt
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
override fun onViewCreated(view: View, savedInstanceState: Bundle) {
btnClick2.setOnClickListener(object:View.OnClickListener{
// here I would like to move to FormActivity
override fun onClick(v: View?) {
activity?.startActivity(Intent(context, FormActivity::class.java))
}
})
}
Current Code
MainActivity.kt
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import androidx.fragment.app.Fragment
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// make the list of fragment
val fragmentList = arrayListOf<Fragment>(
SampleFragment(),
Sample1Fragment()
)
// create instance of adapter
val adapter = SamplePagerAdapter(supportFragmentManager, fragmentList)
/// set adapter
viewPager.adapter = adapter
}
public fun fragmentMethod() {
Toast.makeText(this@MainActivity, "Method called From Fragment", Toast.LENGTH_LONG).show();
}
}
SampleFragment.kt
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import kotlinx.android.synthetic.main.fragment_sample.*
class SampleFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_sample, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
btnClick.setOnClickListener(object:View.OnClickListener{
override fun onClick(v: View?) {
(activity as MainActivity).fragmentMethod()
}
})
}
}
Sample1Fragment.kt
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import kotlinx.android.synthetic.main.fragment_sample1.*
import android.content.Intent
class Sample1Fragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_sample1, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
override fun onViewCreated(view: View, savedInstanceState: Bundle) {
btnClick2.setOnClickListener(object:View.OnClickListener{
// here I would like to move to FormActivity
override fun onClick(v: View?) {
activity?.startActivity(Intent(context, FormActivity::class.java))
}
})
}
}
}
Developping Environment
Android Studio 3.6.1
What I tried to do
It tried to use SingleLiveEvent
recommended on an answer, but I haven't found the appropriate way to implement it on my current code, ListViewModel.kt
and Sample1Fragment.kt
.
Reference: LiveData with SnackBar, Navigation and other events (the SingleLiveEvent case)
ListViewModel.kt
import android.app.usage.UsageEvents
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class ListViewModel : ViewModel() {
private val _navigateToDetails = MutableLiveData<UsageEvents.Event<String>>()
val navigateToDetails : LiveData<UsageEvents.Event<String>>
get() = _navigateToDetails
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
fun userClicksOnButton(itemId: String) {
_navigateToDetails.value =
UsageEvents.Event(itemId) // Trigger the event by setting a new Event as a new value
}
}
These are the error messages I'm facing to
Sample1Fragment.kt
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import kotlinx.android.synthetic.main.fragment_sample1.*
import android.content.Intent
class Sample1Fragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_sample1, container, false)
}
myViewModel.navigateToDetails.observe(this, Observer {
it.getContentIfNotHandled()?.let { // Only proceed if the event has never been handled
fun onViewCreated(view: View, savedInstanceState: Bundle) {
btnClick2.setOnClickListener(object:View.OnClickListener{
// here I would like to move to FormActivity
override fun onClick(v: View?) {
activity?.startActivity(Intent(context, FormActivity::class.java))
}
})
}
})
}
}
This is the error message I'm facing to
回答1:
In Sample1Fragment.kt
you are overriding onViewCreated()
inside onActivityCreated()
method.
This is why you get
Modifier 'override' is not applicable to 'local function'
About navigation:
there is several possible ways how to navigate between different activities and fragments:
- navigation, which is usually the easiest to implement
- callbacks, which are already preset when you create a fragment in Android Studio
- view model, shared between fragment and it's activity. In this case, I suggest using SingleLiveEvent to trigger the event.
来源:https://stackoverflow.com/questions/60625386/how-can-i-manage-fragment-and-activity-considering-its-creation-orders