마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

프래그먼트에 있는 리사이클러뷰가, 프레임 레이아웃에 출력이 안됩니다.

0 추천

리사이클러뷰의 각 항목에 숫자를 1부터 70까지 출력되도록 코드를 작성해 놓은 상태입니다.


프래그먼트에 담아놓은 리사이클러뷰를 화면에 출력시켜주지 않습니다.

 

버튼을 눌렀을때, 프래그먼트를 불러보면, 여기에 담긴 리사이클러뷰가 출력이 되질 않습니다.

 

간단한 텍스트뷰라든지 이미지 같은 것은 잘만 출력시켜주는데, 리사이클러뷰만 출력이 안됩니다.

 

FragmentActivity1.kt

class FragmentActivity1 : Fragment() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        val view: View = inflater.inflate(R.layout.activity_fragment1, container, false)
        
        val dataSet = (1..70).toList()
        recy.adapter = SampleAdapter2(dataSet)         
        return view
    }

   
    class SampleAdapter2(private val dataSet: List<Int>) : RecyclerView.Adapter<SampleAdapter2.NumberViewHolder>() {    

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NumberViewHolder {      
            val layoutView: LinearLayout = LayoutInflater.from(parent.context).inflate(R.layout.activity_bible3927, parent, false) as LinearLayout

            return NumberViewHolder(layoutView)
        }

        override fun getItemCount(): Int = dataSet.size  

        override fun onBindViewHolder(holder: NumberViewHolder, position: Int) {        
            if(position < dataSet.size) {
                holder.number.text = dataSet[position].toString()       
            }
        }

        inner class NumberViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {     
            val number = itemView.findViewById(R.id.textView) as TextView          
    }
}

 

 

★질문하면서, 코드를 넣었다 뺏다 하면서 알아봤는데, 아래 코드를 넣으면 에러가 나고, 안넣으면 에러가 안났습니다. ㅠㅠ 해결했다는 뜻이 아니라, 그냥 이정도만 알아냈다는 것입니다.

val dataSet = (1..70).toList()
recy.adapter = SampleAdapter2(dataSet)
activity_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".HomeActivity"
    tools:showIn="@layout/activity_home">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recy"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        app:layout_constraintBottom_toTopOf="parent"
        app:layout_constraintEnd_toStartOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

 

activity_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="wrap_content"
    android:orientation="vertical">
    <!-- height값을 wrap_content로 해야 글자간 여백이 늘어나는 오류가 생기지 않는다. -->

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="안녕\n하세요" />

</LinearLayout>

 

상쾌한 (1,890 포인트) 님이 2021년 1월 2일 질문
상쾌한님이 2021년 1월 4일 수정
val button1: TextView = findViewById(R.id.reduce2)
or
val button1 = findViewById<TextView>(R.id.reduce2)
FragmentActivity는 이미 안드로이드에서 사용하는 클래스 이름입니다. 이름을 변경하시길...
답변 감사합니다. ^^
val layoutView: LinearLayout = LayoutInflater.from(parent.context).inflate(R.layout.activity_bible3927, parent, false) as LinearLayout

activity_bible3927 이건 뭔가요?
논리적으로는 여기에 activity_item 이 와야 하는 것 같은데..
이상한게 있네요.

1개의 답변

+1 추천
 
채택된 답변

먼저 FragmentActivtity에서 recy초기화 화는 부분이 의심이 가네요. XML또는 코드에 LayoutManager를 세팅해 주셔야 합니다.

코드를 통해 하신다면,

recy.layoutManager = LinearLayoutManger(requireContext)

LinearLahyoutManager의 생성자에 추가 인자들이 있습니다. 방향가 거꾸로된 layout인지 관련된 것들입니다. 생략하면 기본으로 수직으로 된 lenear layout을 레이아웃으로 사용하겠다는 말입니다.

참고로, 님의 경우는 성능향상을 위해서 recy의 width, height 를 MATCH_PARENT로 하고 setHasFixedSize(true)를 해주시는게 일반적입니다.

이게 아니라면, recy의 개별 아이템을 그려주는 레이아웃의 구성을 확인해 봐야 합니다. 혹시 높이가 0은 아닌지.

그리고  onCreate의 adapter에 데이터를 세팅해주는 부분은 onViewCreate같은 뷰가 inflate된 다음에 호출되는 이벤트로 옮겨주시는 게 맞을 것 같습니다. onCreate에 recy관련 코드를 보면 마치 kotlin android extension을 사용하셔서 recy를 가져오신 것 같은데, 아래의 버튼들을 세팅하는 부분은 findViewbyId를 사용하셨네요. 이 부분도 좀 이상해 보이구요. 

아무튼 뷰에 접근하는 것은 뷰가 onCreateView에서  inflate된 다음에 하시는 게 맞습니다. 왜 저코드가 에러가 안 났는지 갑자기 궁금해지네요.

spark (227,530 포인트) 님이 2021년 1월 3일 답변
상쾌한님이 2021년 4월 11일 채택됨
답변 감사합니다. ^^ 레이아웃매니저는 이미 xml코드에 설정해뒀던 상태였습니다. ^^ 그리고 findViewById는 제가 아직 잘 모르던때에 해놓았던 것이라, 지금은 잘못된 것을 이해하지만, 이것은 쓰나 안쓰나 영향을 주지 않는것 같아서요... 그리고, 레이아웃의 구성은 여기에 새로 올려놓았는데 한 번만 봐주시겠어요?

레이아웃의 구성도 별 문제 없으리라 예상해봅니다.

리니어 레이아웃 매니저에 대한것은 코딩 레시피 사이트에서 이미 공부해서 알고 있었습니다.

음... 아무래도 여기서 말씀하신 것은 안해본게 없는것 같습니다. 이것으로는 해결이 되지 않을것 같습니다.

지금 조금 더 알아보니까. 프레임 레이아웃으로 프래그먼트를 호출할때에 문제가 생기는게 아니라, 리사이클러뷰를 프래그먼트에 담을때, 이 때 문제가 생기는 것 같고요. 어댑터 클래스와 뷰홀더 클래스를 정의할 때에는 문제가 없지만, 이 만들어 놓은 어댑터와 뷰홀더를, 리사이클러뷰의 어댑터 부분에 초기화시켜줄때에 문제가 생기는것 같습니다. 왜 그런지 도무지 모르겠습니다..

리사이클러뷰만 화면에 출력시켜보면 잘 출력됩니다. 프래그먼트도 텍스트뷰만 출력시킬 때에는 문제가 없습니다. 그러나 리사이클러뷰를 프래그먼트에 담아서 출력시키려고 할 때에만 문제가 발생합니다.
에러가 났다 안났다 한다는 말이 exception이 있다 없다는 말씀이신지, 아니면 화면에 제대로 출력이 되었다 안되었다 한다는 말씀이신지 좀 헷갈리네요. 만약 진짜 에러라면, 해당 로그가 있을 거구요.
그리고 어댑터가 해당 이슈에 제일 핵심이 되는 클래스가 될 수 있을 것 같은데, 그 부분은 빠져있네요. 올리신 코드만으로는 딱히 문제는 없어 보이는데요.
...