首页 > 解决方案 > 从 MainActivity 类将新字符串注入 Fragment/ViewModel

问题描述

使用 android studio 底部导航活动模板,希望每次从底部导航访问主页时更改我的HomeFragment/页面文本。HomeViewModel当我第一次单击它时,它显示的文本应该与第二次显示的文本不同。

我能够创建一个保存文本输出的变量,并且我创建了一个应该能够更新该变量的函数,但我无法在MainActivity类中调用它。有任何想法吗?

主要活动

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val navView: BottomNavigationView = findViewById(R.id.nav_view)
        val navController = findNavController(R.id.nav_host_fragment)
        val appBarConfiguration = AppBarConfiguration(setOf(
                R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications))


        navView.setupWithNavController(navController)
    }

首页片段

class HomeFragment : Fragment() {

    private lateinit var homeViewModel: HomeViewModel
    var chosenOutput:String = "primary output";

    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View? {
        //using update here crashes the app
        homeViewModel =
                ViewModelProvider(this).get(HomeViewModel::class.java)
        val root = inflater.inflate(R.layout.fragment_home, container, false)
        val textView: TextView = root.findViewById(R.id.text_home)
        homeViewModel.text.observe(viewLifecycleOwner, Observer {
            textView.text = chosenOutput; //changing 'chosenOutput' to 'it' means that text update must take place within HomeViewModel instead of fragment.
        })
       
        return root
    }
    fun update(result: String)
    {
        chosenOutput = result; 
    }
}

主页查看模型

class HomeViewModel : ViewModel() {
    var temp:String = "demo"
    //constructor()
    private val _text = MutableLiveData<String>().apply {
        value = temp;
    }
    fun update(result: String) //function may be obsolete if text change can be done in fragment.
    {
        temp = result; 
    }
    val text: LiveData<String> = _text

}

将字符串注入到我给出的类中的正确方法Fragment是什么ViewModelMainActivity

标签: c#androidkotlinandroid-fragmentsbottomnavigationview

解决方案


您可以更改方法并将chosenOutput变量存储在 中,MainActivity 并在每次选择时更新它HomeFragment

class MainActivity : AppCompatActivity() 
{
    var chosenOutput = "primary output"
    ...

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val navView: BottomNavigationView = findViewById(R.id.nav_view)
        val navController = findNavController(R.id.nav_host_fragment)
        val appBarConfiguration = AppBarConfiguration(setOf(
                R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications))

        navView.apply {
            setupWithNavController(navController)

            setOnNavigationItemSelectedListener { menuItem ->
                when (menuItem.itemId) {
                    R.id.navigation_home -> {
                        chosenOutput = "new value" // <-- Update chosen output here
                        // Add this method to call the `onResume` method in the fragment
                        showFragment(HomeFragment.newInstance())
                    }
                    else { }
                }

                true
        }
    }

    private fun showFragment(fragment: Fragment) {
        supportFragmentManager.beginTransaction()
                .replace(R.id.nav_host_fragment, fragment)
                .addToBackStack(null)
                .commit()
    }
}

然后,您可以Fragment使用此代码检索更新后的字符串。请注意,我添加了companion object以避免创建Fragment.

class HomeFragment : Fragment() 
{
    companion object
    {
        fun newInstance() : HomeFragment
        {
            return HomeFragment()
        }
    }

    override fun onResume() {
        super.onResume()

        val newChosenOutput = (activity as MainActivity).chosenOutput
    }
}

推荐阅读