Search code examples
androidkotlinandroid-fragmentsandroid-view

Android Studio: Set Text in fragment


I've recently picked up an Android Studio project I started a year ago in Kotlin. It features three fragments that can be navigated through by a bottom navigation bar.

Now, to break my current issue down to a simple example that even doesn't work for me: Given there's a the editText object exercise in fragment_home.xml and I want to call and alter it in HomeFragment.kt. I checked every source of advice I could find from Google & Stackoverflow and came up with the following code in HomeFragment.kt (partially pre-coded by AndroidStudio):

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val homeViewModel =
            ViewModelProvider(this).get(HomeViewModel::class.java)

        _binding = FragmentHomeBinding.inflate(inflater, container, false)
        val root: View = binding.root

        val view: View = inflater!!.inflate(R.layout.fragment_home,container,false)

        view.exercise.setText("This is an exceptionally hardcoded string")

The last line stands for every object I tried to reach. I also tried onClickListening for buttons like so:

val btnNewExercise =  view.findViewById<Button>(R.id.btn_new_exercise)
btnNewExercise.setOnClickListener {view

            Toast.makeText(view.context, "New exercise will be generated", Toast.LENGTH_SHORT).show()
            println("Generated a new exercise")
        }

but nothing happens when I start the app/ hit the buttons - I seem to can't get through to the actual view's objects to access them. Even ran into NullPointerExceptions on my way to a solution.

I could supply the fragment and layout files if needed - just thought this way it might be easier at first.

If anybody could tell me where I'm wrong I'd be really grateful! Thanks in advance!


Solution

  • You inflated the layout twice.

    Remove this. You already inflated the layout using view binding in the FragmentHomeBinding.inflate... call

    val view: View = inflater!!.inflate(R.layout.fragment_home,container,false)
    

    and replace

    view.exercise.setText("This is an exceptionally hardcoded string")
    

    with (using binding

     binding.exercise.setText("This is an exceptionally hardcoded string")
    

    then the last line on your onCreateView should be

       return binding.root
    

    Note: You should have these class properties:

    private var _binding: FragmentHomeBinding? = null
    private val binding get() = _binding!!
    

    So it will look like this:

                   //move your view model as a class property so it will be accessible by other class methods
                     private val homeViewModel =
                              ViewModelProvider(this).get(HomeViewModel::class.java)
    
     
                     private var _binding: FragmentHomeBinding? = null
                     private val binding get() = _binding!!//transform to immutable
                
                     override fun onCreateView(
                            inflater: LayoutInflater,
                            container: ViewGroup?,
                            savedInstanceState: Bundle?
                        ): View? {
    
                            
                    
                            _binding = FragmentHomeBinding.inflate(inflater, container, false)
                          
                           //use the immutable view binding property
                            binding.exercise.setText("This is an exceptionally hardcoded string")
                
                            return binding.root
                       }
    

    For more info, read view binding