개발자 끄적끄적

목록표시 UI 본문

안드로이드 프로그래밍

목록표시 UI

햏치 2023. 5. 14. 12:49

<Recycler View>
- 초기에 항목을 나열하는 컨테이너로 ListView가 있었다
- 효율적인 Recycler View가 등장하고 ListView는 사용 지양
- 구성요소
  - RecyclerView.Adapter - ViewHolder를 생성
  - ViewHolder와 데이터 연결
 - RecyclerView.ViewHolder - 뷰를 담아두는 상자
  - LayoutManager - 항목 뷰들의 배치를 결정, 리스트, 그리드 등
  - RecyclerView - Adapter로부터 ViewHolder를 가져와서 LayoutManager에 의해 뷰를 배치


<RecyclerView.Adapter 생성>
- RecyclerView.Adapter를 상속하여 CustomAdapter를 생성
- 일반적으로, 사용할 ViewHOlder를 같이 정의
class CustomAdapter(private val viewModel: MyViewModel) :
RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
inner class ViewHolder(private val view: View) :
RecyclerView.ViewHolder(view) {
}
// ViewHolder 생성, ViewHolder 는 View 를 담는 상자
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder
// ViewHolder 에 데이터 연결
override fun onBindViewHolder(viewHolder: ViewHolder, position: Int)
override fun getItemCount()
}



<동작 개요 정리>
- RecyclerView에서 Adapter에게 필요한 만큼의 ViewHolder 생성을 요청하여 ViewHolder를 받아 두고 있다
  - onCreateViewHolder()가 호출

- 리스트 항목 내용이 변경되어야 할 때 항목에 해당하는 ViewHolder에 데이터를 채우도록 Adapter에게 요청
  - onBindViewHolder()가 호출



<컨텍스트 메뉴>
- 어떤 뷰를 롱클릭했을 때 나타나는 해당 뷰의 내용과 관련된 메뉴
- 목록을 나타내는 컨테이너 위젯에서 항목을 롱클릭하면 해당 항목관련된 컨텍스트 메뉴를 나타내고 
  - 메뉴를 선택하면 해당 항목에 대해 선택한 기능을 수행

- 구현방법
  - registerForContextMenu(View) - 컨텍스트 메뉴를 생성할 위젯 지정
 - onCreateContextMenu() 재정의 - 컨텍스트 메뉴 생성
  - onContextItemSelected() 재정의 - 메뉴 항목 선택 처리



<스피너>
- 목록을 보여주는 컨테이너 위젯인데, 평소에는 목록이 보이지 않고 클릭하면 밑에 목록을 보여주는 위젯
  - 다른 운영체제에서는 콤보 박스라고 부르기도 한다

- 스피너 위젯에 항목 뷰를 제공하는 어댑터를 만들어서 사용
  - 어댑터를 사용하는 컨테이너 위젯을 어댑터 뷰라고 한다
  - ListView, GridView와 같은 다른 어뎁터 뷰도 있으나 RecyclerView로 대체



<스피너와 어댑터>
- 레이아웃에 Spinner추가
- 커스텀 어댑터를 만들어도 되고, 간단하게는 ArrayAdapter 같은 클래스를 이용하면 편하다
- ArrayAdapter(컨텍스트, 항목 레이아웃, 데이터_리스트)

- 다이얼로그에서 사용하는 예제 코드, 액티비티에서도 비슷하게 하면 된다
  - ex)
class ItemDialog(private val itemPos: Int = -1): BottomSheetDialogFragment() {
private val viewModel by activityViewModels<MyViewModel>()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) : View = inflater.inflate(R.layout.item_dialog_layout, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val spinner = view.findViewById<Spinner>(R.id.spinner)
val adapter = ArrayAdapter(requireContext(),
android.R.layout.simple_spinner_item, MyViewModel.icons.keys.toList())
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinner.adapter = adapter // 스피너 위젯과 어댑터 연결




<FAB(Floating Action Button)>
- 레이아웃에 FAB 추가, 위치는 적당히
- 코드에 클릭 리스너 추가




<FAB 클릭 리스너>
- 일반 버튼 클릭 리스너와 동일
  - ex)
class MainActivity : AppCompatActivity() {
private val viewModel by viewModels<MyViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val floatingActionButton = findViewById<FloatingActionButton>(R.id.floatingActionButton)
floatingActionButton.setOnClickListener {
ItemDialog().show(supportFragmentManager, "ItemDialog")
// 앞의 ItemDialog 정의에서 생성자 인자가 -1이면 ViewModel에 데이터 추가로 동작
}