0

I am new in android, and I try to use the view binding for my app, there is not any mistake on my code, but after running, it is crashed, when I look at the Logcat , there is not any info about crash there is only one info about

internal inner class MenuAdapter(context: MyFragment

as a

Parameter 'context' is never used, any idea?

   class MyFragment : Fragment() {

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

    private var mTitle = arrayOf("menu1", "menu2", "menu3", "menu4", "menu5")

    private var images = intArrayOf(R.drawable.ic_menu1,
            R.drawable.ic_menu2,
            R.drawable.ic_menu3,
            R.drawable.ic_menu4,
            R.drawable.ic_menu5)

    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View {

        _binding = MyFragment.inflate(inflater, container, false)

        val listView: ListView = binding.listViewMenu
        val adapter = MenuAdapter(this, mTitle, images)
        listView.adapter = adapter

        listView.onItemClickListener = AdapterView.OnItemClickListener { _, _, position, _ ->
            if (position == 0) {
                val intent = Intent(this.context, Menu1::class.java)
                startActivity(intent)
            }
            if (position == 1) {
                val intent = Intent(this.context, Menu2::class.java)
                startActivity(intent)
            }
            if (position == 2) {
                val intent = Intent(this.context, Menu3::class.java)
                startActivity(intent)
            }
            if (position == 3) {
                val intent = Intent(this.context, Menu4::class.java)
                startActivity(intent)
            }
            if (position == 4) {
                val intent = Intent(this.context, Menu5::class.java)
                startActivity(intent)
            }
          

        }

        return binding.root

    }

    internal inner class MenuAdapter(context: MyFragment,
                                   private var rTitle: Array<String>,
                                   private var rImgs: IntArray) : ArrayAdapter<String?>(requireContext(),
        R.layout.row_menu,
        R.id.textViewMenu, rTitle) {
        override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
            val layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater

            val menuRow = RowMenuBinding.inflate(layoutInflater, parent, false)
            val images = menuRow.imageMenu
            val myTitle = menuRow.textViewMenu

            images.setImageResource(rImgs[position])
            myTitle.text = rTitle[position]
            return binding.root
        }}}
  • I think I have an idea. Try to handle UI elements like binding.listViewMenu in `onViewCreated`. For onCreateView just leave 2 lines: 1. binding assignment and return binding.root Also, another question: Shouldn't you use MyFragmentBinding instead of MyFragment ? – Ionut J. Bejan Jan 17 '22 at 11:26
  • I bet there is a crash info in log, but app gets killed and log is cleaned then. try to configure log as in answer [HERE](https://stackoverflow.com/questions/35415101/prevent-android-logcat-clear-during-app-restart) and post stacktrace – snachmsm Jan 17 '22 at 11:30
  • @Ionut J. Bejan, I try to apply onViewCreated, but still is the same –  Jan 17 '22 at 15:00

3 Answers3

1

In your adapter getView() you are returning binding.root which refers to the fragment layout binding. You should be returning menuRow.root instead.

And you should have an exception in the logcat. Just make sure you don't have any logcat filters or such that hide it.

laalto
  • 150,114
  • 66
  • 286
  • 303
0

Your onCreateView(...) should only do

 override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View {

        _binding = MyFragment.inflate(inflater, container, false)
        return binding.root
}

All the other stuff you're doing should be in:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    
    val listView: ListView = binding.listViewMenu
    val adapter = MenuAdapter(this, binding.title, images)
    listView.adapter = adapter
    ... etc

}
Martin Marconcini
  • 26,875
  • 19
  • 106
  • 144
0

I would suggest a few changes to your code. The Fragment class can now receive a xml layout so you should pass it there. The change would look like this:

class MyFragment : Fragment(R.layout.my_main_fragment) // replace with the name of your layout

Each XML layout gets a respective binding class that corresponds with the XML layout name. For example, if your layout is called my_main_fragment, the class will receive the name of MyMainFragmentBinding. Following that change, you will bind your view inside the onViewCreated() method. It will look like:

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

    override fun onViewCreated(
        view: View,
        savedInstanceState: Bundle?) 
    {
        super.onViewCreated(view, savedInstanceState)
        _binding = MyMainFragmentBinding.bind(view)
    
    // ...other code from onCreateView
    }

    internal inner class MenuAdapter(context: MyFragment, ...

Also, don't forget to add _binding = null in the onDestroyView() method

To answer the question from the comments: Inside getView() of your MenuAdapter, you should be returning menuRow.root.

You can read more about view binding at the android developers page: https://developer.android.com/topic/libraries/view-binding

Or see an example here: https://github.com/android/architecture-components-samples/blob/master/ViewBindingSample/app/src/main/java/com/android/example/viewbindingsample/BindFragment.kt#L36-L41

Filip Petrovski
  • 425
  • 3
  • 6
  • I do it but it is throw an error for an error here myTitle.text = rTitle[position] return binding.root for binding as Unresolved reference: binding –  Jan 17 '22 at 14:12
  • 1
    @Barışzüngür I believe you should `return menuRow.root` in your getView on the MenuAdapter. – Filip Petrovski Jan 17 '22 at 15:04
  • tnx so much I get it :) –  Jan 17 '22 at 15:25