android / views-widgets-samples

Multiple samples showing the best practices in views-widgets on Android.
Apache License 2.0
5.03k stars 3.01k forks source link

It sames that RecycleView in Fragment FrameLayout can not be recognized #242

Open showkeyjar opened 1 year ago

showkeyjar commented 1 year ago

I create a RecycleView in FrameLayout which belong one Fragment but it sames that android can not recognize it. I tried binding.view_id and use findviewbyid, those functions all no use. android studio has no error, but do not display view.

this is my layout.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android">
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.rec.RecFragment">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rec_view"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:scrollIndicators="bottom"
        android:fadeScrollbars="false"
        android:layout_gravity="center_vertical"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:clickable="true"
        android:scrollbarAlwaysDrawHorizontalTrack="true"
        android:scrollbars="none"
        app:layoutManager="LinearLayoutManager"/>

</FrameLayout>

and this is my fragment.kt

package com.ml.test.ui.rec

import android.R
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.ml.test.databinding.FragmentTopBinding
import com.ml.test.utils.FaceAdapter
import com.ml.test.utils.NewFace

class RecFragment : Fragment(){
    private lateinit var recViewModel: RecViewModel
    private var _binding: FragmentTopBinding? = null

    private lateinit var recyclerView: RecyclerView
    private lateinit var newsArrays:ArrayList<NewFace>

    lateinit var imageId:Array<String>
    lateinit var heading:Array<String>

    // This property is only valid between onCreateView and
    // onDestroyView.
    private val binding get() = _binding!!

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

        _binding = FragmentTopBinding.inflate(inflater, container, false)
        val root: View = binding.root
        try{
            // val rootView: View = inflater.inflate(com.ml.test.R.layout.fragment_rec, container, false) // not work
            // recyclerView = rootView.findViewById(com.ml.test.R.id.rec_view)  // not work
            // recyclerView = root.findViewById(com.ml.test.R.id.rec_view)  // not work
            recyclerView = root.recView // not work
            Log.d("rec_frag", "find Recycle View")
        }catch (e: Exception){
            Log.i("rec_flag", e.message.toString())
        }
        dataInitialize()
        if(::recyclerView.isInitialized) {
            // recyclerView.layoutManager = LinearLayoutManager(activity)
            var faceAdapter = FaceAdapter(newsArrays)
            faceAdapter.notifyDataSetChanged()
            recyclerView.adapter = faceAdapter
            recyclerView.setHasFixedSize(true)
            Log.d("rec_frag", "Recycle View init data")
        }

        return root
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }

    private fun dataInitialize(){
        newsArrays = arrayListOf()

        imageId = arrayOf(
            "https://i.imgur.com/DvpvklR.png",
            "https://i.imgur.com/DvpvklR.png"
        )

        heading = arrayOf(
            "test1",
            "test2"
        )

        for (i in imageId.indices){
            val news = NewFace(imageId[i], heading[i])
            newsArrays.add(news)
        }

    }

}

and debug out put: findViewById can not be null

showkeyjar commented 1 year ago

I fig it out, because I use wrong Fragment Binding class

I must use

import com.ml.test.databinding.FragmentRecBinding

not

import com.ml.test.databinding.FragmentTopBinding

and this class is auto generate by Framework, and if u copy code, it has no error even use wrong class.

by the way, why user must care those class?