Search code examples
androidandroid-fragmentskotlinandroid-tablayout

How to change dynamically TextView and ImageView Elements for each Fragment


Background
I am trying to populate fragments' contents through one function. The fragment list changes according to the Navigation Item Selected.
IE: I have 2 Navigation items ("Fruits,Animals") for both, I have 3 categories where the thing that changes is the image and the description, sort of like this:

       NavButton>Fruits                   NavButton>Animals
Apple -> Image and description     Alligator -> Image and description
Banana -> Image and description    Bat -> Image and description
Cherry -> Image and description    Cat -> Image and description


Instead of creating 6 Fragment Layouts and activities, I created 3 and the idea is to clear and set text/images as needed. This way I would be able to save time and memory instead of creating one fragment per activity when the only thing that changes is the text in the textView (already declared in the values) and the image on the imageView (in the drawable section).
Problem
I have not found an implementation to change the textView nor the Imagesrc for ImageView. I have tried per each fragment (which causes FC). I have not found a way to do it for the drawable
Code
Code for the adapter which populates the Tabs

import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentPagerAdapter
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import com.company.app.R.id.TextViewFragmentFirst
import com.company.app.R.layout.fragment_fragment_first
import com.company.app.fragments.FragmentFirst
import com.company.app.fragments.FragmentSecond
import kotlinx.android.synthetic.main.fragment_fragment_first.*

class CustomPageAdapter(FragManager:FragmentManager): FragmentPagerAdapter(FragManager) {
    //var obj_FragManager = FragManager
    var fragManagerItems:ArrayList<Fragment> = ArrayList()
    var fragManagerTitles:ArrayList<String> = ArrayList()
    var fragmentTxtContents:ArrayList<String> = ArrayList()
    var fragmentImgObjs:ArrayList<Int> = ArrayList()
    lateinit var textViewToChange:TextView
    lateinit var imageViewToChange:ImageView
            //findViewById(R.id.TextViewFragmentFirst) as TextView
    fun removeFragments()
    {
    fragManagerItems.clear()
    }
    fun addFragments(fragmentItem:Fragment,fragmentTitle:String,fragmentTxtContent:String,fragmentImgObj:Int)
    {
    fragManagerItems.add(fragmentItem)
    fragManagerTitles.add(fragmentTitle)
    when (fragmentItem){
        FragmentFirst()-> print("x == 1") //Here I would like to set textViewToChange & imageViewToChange
        FragmentSecond()-> print("x == 2")//Here I would like to set textViewToChange & imageViewToChange
        FragmentThird()-> print("x == 3")//Here I would like to set textViewToChange & imageViewToChange
        else -> {
            print("no valid fragment casted!")
        }
        }
        textViewToChange!!.setText(fragmentTxtContent)
        imageViewToChange!!.setImageResource(R.drawable.ic_iconapp) // Here it would need to be based on the fragmentImgObj
    }
    override fun getItem(position: Int): Fragment {
        return fragManagerItems[position]
    }

    override fun getCount(): Int {
        return fragManagerItems.size
    }
    override fun getPageTitle(position: Int): CharSequence {
        return fragManagerTitles[position]
    }

}

Fragments are standard, nothing have changed

class FragmentFirst : Fragment() {

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment "

        return inflater!!.inflate(R.layout.fragment_fragment_first, container, false)

    }


Approaches used
1. I have tried to use import kotlinx.android.synthetic.main.fragment_fragment_first.* along with the textviewID and the setText property within the fragment OnCreateView before the 'return' but only causes a FC. I would like to do it instead on the adapter, however, I ahve not found a way to even set the variables as needed.


Solution

  • I found the solution as implement it on the main activity instead of the adapter

    import kotlinx.android.synthetic.main.fragment_fragment_first.*
    import kotlinx.android.synthetic.main.fragment_fragment_second.*
    import kotlinx.android.synthetic.main.fragment_fragment_third.*
        ...
        override fun onNavigationItemSelected(item: MenuItem): Boolean {
        // Handle navigation view item clicks here.
        objPageAdapter = CustomPageAdapter(supportFragmentManager)
        when (item.itemId) {
            R.id.nav_fruits -> {
                objPageAdapter!!.removeFragments()
                objPageAdapter!!.addFragments(FragmentFirst(),getString(R.string.txt_tab_fruits_Element_1))
                objPageAdapter!!.addFragments(FragmentSecond(),getString(R.string.txt_tab_fruits_Element_2))
                objPageAdapter!!.addFragments(FragmentThird(),getString(R.string.txt_tab_fruits_Element_3))
                ViewPagerMain.adapter = objPageAdapter
                TabLayoutMain.setupWithViewPager(ViewPagerMain)
                this.textViewFragment_1.text = getString(R.string.txt_txtView_fruits_Element_1)
                this.textViewFragment_2.text = getString(R.string.txt_txtView_fruits_Element_2)
                this.textViewFragment_3.text = getString(R.string.txt_txtView_fruits_Element_3)
                ...
    

    I assume that you have to wait until all the elements in the tablayout have been populated and you cannot do it in the middle of the tab population since XMLs have not been created.