How can I manage fragment and activity considering its creation orders?

左心房为你撑大大i 提交于 2020-05-14 13:00:10

问题


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:

  1. navigation, which is usually the easiest to implement
  2. callbacks, which are already preset when you create a fragment in Android Studio
  3. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!