androidkotlinfragmentandroid-lifecyclefragment-lifecycle

Kotlin : create content in onCreateView


I'm generating some content thanks to my function getInfoTrafic(). But when I display it on my screen, my screen is load and after (like a second), my content is generated.

Why? Is that normal for a fragment? Is it possible to do what I want?

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    val view = inflater.inflate(R.layout.infos_trafic, container, false)
    getInfosTrafic(view)
    return view
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
}

These are my functions.

private fun getInfosTrafic(view : View) {
    val resultActus = Fuel.get("MYAPI").responseJson { request, response, result ->
        println("Reponse : "+response.toString())
        result.fold({
            json ->
            Log.i(TAG, (json.content))
            parseInfosTrafic(json.content, view)
        }, {
            err ->
            Log.i("error", err.toString())
        })
    }
}

And this one is adding my element into my layout

    private fun parseInfosTrafic(json: String, view : View): ArrayList<String> {    
        val array = JSONArray(json)
        val infos : ArrayList<String> = ArrayList<String>()
        val hashMap = HashMap<Int, JSONObject>()
        val llScrollInfoTraficFav = view.findViewById<LinearLayout>(R.id.llScrollInfoTraficFav)
        val llScrollInfoTraficTL= view.findViewById<LinearLayout>(R.id.llScrollInfoTraficTL)

        (0 until array.length()).forEach{
          for(i in 0..3){
            val evenOdd = if (i %2 == 0) "even" else "odd"

            val item = array.getJSONObject(it)
            val ...

            val mpLinearLayoutFirst = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
            val LinearLayoutFirst = LinearLayout(view.context)
            LinearLayoutFirst.layoutParams = mpLinearLayoutFirst
            LinearLayoutFirst.orientation = LinearLayout.VERTICAL
            LinearLayoutFirst.tag = "result"
            mpLinearLayoutFirst.bottomMargin = 5.toPx()

            val mpLinearLayoutSecond = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
            val linearLayoutSecond = LinearLayout(view.context)
            linearLayoutSecond.layoutParams = mpLinearLayoutSecond
            linearLayoutSecond.orientation = LinearLayout.VERTICAL
            linearLayoutSecond.setPadding(35.toPx(),35.toPx(),35.toPx(),35.toPx())
            linearLayoutSecond.background = resources.getDrawable(R.drawable.whit_bg_and_shadow, activity?.theme)
            linearLayoutSecond.tag = "visibleNotChangeable"

            LinearLayoutFirst.addView(linearLayoutSecond)

            val mpLinearLayoutThird = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
            val linearLayoutThird = LinearLayout(view.context)

            linearLayoutSecond.addView(linearLayoutThird)

            val rubikMedium = ResourcesCompat.getFont(view.context, R.font.rubik_medium)

            val wwRes = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)
            val dateView = TextView(view.context)
            dateView.setTextAppearance(R.style.blueItalic)
            dateView.layoutParams = wwRes
            dateView.typeface = rubikMedium
            dateView.text = date
            dateView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16F)

            val title = TextView(view.context)
            title.setTextAppearance(R.style.citySearch)
            title.layoutParams = wwRes
            title.typeface = rubikMedium
            title.text = titleJson
            title.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16F)

            linearLayoutThird.addView(dateView)
            linearLayoutThird.addView(title)

            val linearLayoutHidden = LinearLayout(view.context)
            val mpLinearLayoutHidden = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
            linearLayoutHidden.layoutParams = mpLinearLayoutHidden
            linearLayoutHidden.setPadding(35.toPx(),35.toPx(),35.toPx(),35.toPx())
            linearLayoutHidden.orientation = LinearLayout.VERTICAL
            linearLayoutHidden.background = resources.getDrawable(R.drawable.gray_bg, activity?.theme)
            linearLayoutHidden.visibility = LinearLayout.GONE
            linearLayoutHidden.tag = "toToggle"

            val layoutResume = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
            val resume = WebView(view.context)
            resume.layoutParams = layoutResume
            resume.settings
            resume.setBackgroundColor(Color.TRANSPARENT)
            resume.loadData(content, "text/html; charset=utf-8", "utf-8")

            linearLayoutHidden.addView(resume)

            val layoutButton =  LinearLayout.LayoutParams(40.toPx(),  40.toPx())
            val buttonToggle = Button(view.context)
            layoutButton.topMargin = (-20).toPx()
            layoutButton.gravity = Gravity.CENTER
            buttonToggle.layoutParams = layoutButton
            buttonToggle.background = resources.getDrawable(R.drawable.arrow_down_blue_circle, activity?.theme)
            buttonToggle.tag = "toToggleButton"

            buttonToggle.setOnClickListener {
                val viewParent = it.parent
                if (viewParent is LinearLayout) {
                    val taggedView = viewParent.findViewWithTag<View>("toToggle")

                    taggedView.visibility = when {
                        taggedView.visibility == View.GONE -> View.VISIBLE
                        else -> View.GONE
                    }
                }

            }

            LinearLayoutFirst.addView(linearLayoutHidden)
            LinearLayoutFirst.addView(buttonToggle)

            if(evenOdd == "even"){
                llScrollInfoTraficFav.addView(LinearLayoutFirst)
            }else{
                llScrollInfoTraficTL.addView(LinearLayoutFirst)
            }

        }
        return infos

    }

Solution

  • You should not make operations on the UI thread before the view is created. The method onCreateView() should be used only to inflate the layout and returning the view. Once you have returned the view and the system displays the UI, you can start with your Fragment business logic. Move your code under onViewCreated() method and avoid to make long-time operation in the main thread (the one in which Android updates the UI)

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
       return inflater.inflate(R.layout.infos_trafic, container, false)
    }
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        getInfosTrafic(view)
    }