본문 바로가기
카테고리 없음

회고록의 진행[생존 이야기]

by 덩얼이 2023. 8. 22.
반응형

앱 개발 숙련

발표가 끝나고 팀원이 새로 바뀌었다. 팀원이 바뀌면서 새로운 개인과제와 학습이 열렸다. 학습 내용은 뷰 바인딩, 어댑터 뷰, 어댑터의 종류, 리싸이클러뷰, 리스트뷰, 프래그먼트에 대해서 학습을 새로히 배울 것이 많은 세션이 열렸다. 그럼 새롭게 배우는 부분을 알아보자.

 

뷰 바인딩

뷰 바인딩이란 무엇일까?

- 뷰와 상호작용하는 코드를 쉽게 작성할 수 있다.

- 모둘에서 사용 설정된 뷰 바인딩은 모듈에 있는 각 XML 레이아웃 파일의 결합 클래스르 생성

- 바인딩 클래스의 인스턴스에는 상응하는 레이아웃에 ID가 있는 뷰의 직접 참조가 포함됨

- 대부분의 경우 findViewById를 대체한다.

 

이러한 특징이 있다. 여기서 차이점에 대해서 말하고 넘어가야하는데

 

findViewById와의 차이점

1) NullSafe

- 뷰 바인딩은 뷰의 Direct References 즉 직접 참조를 생성하므로 유효하지 않은 뷰 ID로 인해 null 포인터 예외가 발생할 위험이 없다.

- 즉, 레이아웃에 아직 생성되지 않은 뷰의 참조를 얻어(null 상태) 해당 뷰의 속성을 사용하려 할 때 발생하는 NPE를 방지 한다는 것이다.

- 레이아웃의 일부 구성에만 뷰가 있는 경우 결합 클래스에서 참조를 포함하는 필드가 @Nullable로 표시됨

 

2) Type safety

- 각 바인딩 클래스에 있는 필드의 유형이 XML 파일에서 참조하는 뷰와 일치한다.

- 즉, 클래스 변환 예외가 발생할 위험이 없다.

---> 쉽게 말해서 타입을 가지고 있기 때문에 imageView.text 같이 타입이 다른 경우 발생하는 오류를 방지할 수 있다.

 

이제 뷰 바인딩을 사용해보자

 

사용을 하려면 gradle 설정을 해야한다.

android{
	...
    
    // AndroidStudio 3.6 ~ 4.0
    viewBinding{
    	enabled = true
    }
    
    // AndroidStudio 4.0 ~
    buildFeatures{
    	viewBinding = true
    }
}
```

이렇게 그래들에 각 안드로이드 버전에 맞는 방법으로 선언해줘야한다. 그럼 액티비티에서 사용하는법을 알아보자.

private lateinit var binding:ActivityMainBinding

binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)

기존에 있던 액티비티의 기본 설정에서 이렇게 설정을 바꾸어 주어야 한다. 자 이렇게 되면 뷰 바인딩을 이용할 수 있는것이다.

 

 

반응형

ListView, GridView

각 뷰를 쓰려면 필요한 어댑터에 대해서 알아보자. 그럼 어댑터 뷰 라는것은 무엇일까?

 

- 어댑터 뷰는 여러개의 항목을 다양한 형식으로 나열하고 선택 할 수 있는 기능을 제공하는 뷰라고 한다.

여기서 어댑터란 저번 포스팅에서 자세하게 다루진 않았다. 바로 리스트뷰에 쓰인게 어댑터 뷰인데 간단하게 설명하고 넘어갔었다. 이제 자세하게 더 알아보자. 

 

어댑터

- 데이터를 관리하며 데이터 원본과 어댑터뷰 사이의 중계 역할

1. 어댑터뷰가 어댑터를 사용하기 위해서는 먼저 데이터 원본이 어댑터에 설정되어야 하고, 어댑터뷰에는 어댑터가 설정되어야한다.

2.어댑터뷰는 항목을 표시하기 위해서 먼저 표시할 항목의 총 개수를 알 필요가 있을것이다. 이때 어댑터 뷰는 어댑터의 getCount()란 메소드를 통해 현재 어댑터가 관리하는 데이터 항목의 총 개수를 반환

3.어댑터 뷰는 어댑터의 getView()란 메소드를 통해서 화면에 실제로 표시할 항목뷰를 얻고, 이를 화면에 표시한다.

 

 이렇게 말로만 하면 이해하기 쉽지 않다. 그림으로 살펴보자.

이렇게 그림으로 보면 쉽게 이해할 수가 있다!

여기서 어댑터의 종류는 매우 많지만 그림으로 빠르게 살펴보자.

대표적인 리스트뷰에 대해서 코드로 살펴보도록 하자.

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // 데이터 원본 준비
        val items = arrayOf<String?>("item1", "item2", "item3", "item4", "item5", "item6", "item7", "item8", "item5", "item6", "item7", "item8", "item5", "item6", "item7", "item8", "item5", "item6",  "item7", "item8")

        //어댑터 준비 (배열 객체 이용, simple_list_item_1 리소스 사용
        val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, items)

   }
}

이것은 String으로 어댑터에 사용하면서 xml 리소스를 참조해서 사용할 수 있게된다. 그럼 리스트뷰에 어댑터를 연결해 보아야겠지.

   // 어댑터를 ListView 객체에 연결
        binding.listView.adapter = adapter

이렇게 메인 엑티비티에서 마지막에 리스트뷰 객체에 연결을 해줌으로써 이제 사용을 할 수 있게 되는것이다. 이러한 방법으로 어댑터를 사용하는 법을 알아보았다.

 

RecyclerView

그럼 리싸이클러뷰에 대해서 알아보자. 일단 앞전에 설명했던 리스트뷰는 사용을 추천하지는 않다. 왜냐면 둘의 차이점부터 살펴보자.

ListView RecyclerView
- 사용자가 스크롤 할 때마다 위에 있던 아이템은 삭제, 맨아래의 아이템은 생성되길 반복함 -사용자가 스크롤 할 때, 위에 있던 아이템은 재활용 돼서 아래로 이동하여 재사용함
-아이템이 100개면 100이 삭제, 생성이됨 = 반복적으로 이렇게 돼서 성능에 좋지 않음 -100개여도 10개 정도 재사용을함 = ListView의 단점을 보완

이렇게 각 리스트뷰에 대해 차이점이 있다. 그럼 리싸이클러뷰를 사용하려면 어떻게 해야할까?

 

RecyclerView 사용하기

1) Adapter

- 어댑터란 테이블을 목록 형태로 보여주기 위해 사용되는것, 데이터를 다양한 형식의 리스트 형식을 보여주기 위해서 데이터와 RecylerView 사이에 존재하는 객체

- 즉 리싸이클러뷰와 데이터 통신을 위한 연결체이다.

 

2) ViewHolder

- 화면에 표시될 데이터나 아이템들을 저장하는 역할

- View를 재사용하기 위해서 이 View를 기억해야함으로 ViewHolder가 이 역할을 하게 된다.

 

class MyAdapter(val mItems: MutableList<MyItem>) : RecyclerView.Adapter<MyAdapter.Holder>() {

    interface ItemClick {
        fun onClick(view : View, position : Int)
    }

    var itemClick : ItemClick? = null

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
        val binding = ItemRecyclerviewBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return Holder(binding)
    }

    override fun onBindViewHolder(holder: Holder, position: Int) {
        holder.itemView.setOnClickListener {  //클릭이벤트추가부분
            itemClick?.onClick(it, position)
        }
        holder.iconImageView.setImageResource(mItems[position].aIcon)
        holder.name.text = mItems[position].aName
        holder.age.text = mItems[position].aAge
    }

    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

    override fun getItemCount(): Int {
        return mItems.size
    }

    inner class Holder(val binding: ItemRecyclerviewBinding) : RecyclerView.ViewHolder(binding.root) {
        val iconImageView = binding.iconItem
        val name = binding.textItem1
        val age = binding.textItem2
    }
}

이것은 리싸이클러뷰의 어댑터이다. 자세히 살펴보면 위의 리스트 뷰의 어댑터와는 조금 다른데 인터페이스를 선언을 해줌으로써 

 분리된 책임과 모듈성, 유연한 이벤트 처리, 코드 재사용, 단일 책임 원칙

이러한 이유로 인터페이스를 쓰는데 자세히 생각해보면 리싸이클러뷰는 뷰를 재사용한다고 했다. 그러면 이러한 점은 필연적인것이다.

위의 코드로 어댑터를 선언해주면 된다.

 

마무리하며

발제 이후에 지급된 강의에는 금방 할 줄 알았는데 내용이 꽤 많아졌다. 다 할 수 있을줄 알았는데.. 많다,, 엄청 많아..🤮

다음에는 프래그먼트를 알아보고 사용법에 대해서 알아보겠다. 깃허브를 다루고 프로젝트를 정리하면서 시간을 보냈던 터라 학습이 크게 이루어지지 않았다,,! 내일 모두 정리해보려한다. 언제나 화이팅!

반응형