불순분자 Kotlin [17] - 기능 구현하기

불순분자들·2022년 8월 15일
0

List App 만들기

목록 보기
17/18

Floating Action Button

안드로이드 기능을 구현하기 위해 기본 작업을 트리거하는 원형 버튼인 플로팅액션버튼을 추가해 줄 것이다.
xml에 아래의 코드를 추가해주면 된다.

<com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/btn_write"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="32dp"
        android:layout_marginBottom="32dp"
        android:clickable="true"
        android:elevation="10dp"
        android:backgroundTint="#448AFF"
        app:tint="@color/white"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:srcCompat="@drawable/img_write" />
android:elevation="10dp"

위 코드는 아이콘이 살짝 떠보이게해서 입체감을 준다.

app:tint="@color/white"
android:backgroundTint="#448AFF"

위 코드는 이미지의 색 디자인을 변경하기 위한 코드이다.

Dialog 커스텀

Dialog 커스텀을 하기 위한 위젯은 TextInputLayout이다.
이것은 EditText를 기반으로 유연한 동작을 보여주는 구글의 레이아웃이다.
TextInputLayout의 스타일은 기본적으로 두가지로 FilledBox, OutlinedBox 스타일이 있다.
TextInputLayout 안에는 TextInputEditText를 사용할 수 있다.
예제는 아래와 같다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="16dp"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical">

    <com.google.android.material.textfield.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:counterEnabled="true"
        app:counterMaxLength="20">

        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/et_memo"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:fontFamily="@font/kotra_hope"
            android:singleLine="true"
            android:maxLines="1"
            android:maxLength="20"
            android:hint="메모를 남겨주세요 !"/>

    </com.google.android.material.textfield.TextInputLayout>

</LinearLayout>
android:singleLine="true"
android:maxLines="1"

위 코드는 1줄로 제한하기 위한 코드이다. -> 엔터를 눌러도 두번째 줄로 넘어가지 않는다.

android:maxLength="20"

위 코드는 최대 길이를 20으로 제한한다.

android:hint="메모를 남겨주세요 !"

위 코드는 힌트를 생성하는데 클릭시 스타일에 맞게 위치하게 된다.

FAB를 통해 작성하기 버튼 구현

binding.btnWrite.setOnClickListener {
            val bindingDialog = DialogEditBinding.inflate(LayoutInflater.from(binding.root.context), binding.root, false)

            AlertDialog.Builder(this)
                .setTitle("오늘의 할 일은 ?")
                .setView(bindingDialog.root)
                .setPositiveButton("작성", DialogInterface.OnClickListener { dialog, i ->
                    // 작성 버튼 이벤트 처리
                    val todoItem = ListInfo()
                    todoItem.listContent = bindingDialog.etMemo.text.toString()
                    // pattern은 이러한 형식을 유지하겠다는 구문이고, format(Date()) 메서드가 현재 시간을 가져와준다.
                    todoItem.listDate = SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())
                    listAdapter.addListItem(todoItem) // 어댑터의 전역변수의 arraylist 쪽에 아이템 추가하기위한 메소드 호출
                    listAdapter.notifyDataSetChanged() // 리스트 새로고침 -> 어댑터가 한 사이클 돌게 됨. 고로 아이템이 표출됨.
                })
                .setNegativeButton("취소", DialogInterface.OnClickListener { dialog, i ->
                    // 취소 버튼 이벤트 처리
                })
                .show()
        }

위 코드는 AlertDialog를 통해 작성한 코드로 setTitle은 제목을 설정, setView는 커스텀한 뷰를 보여준다.
ListInfo()를 todoItem으로 객체를 생성해서 listContent와 listDate를 사용하였다.

addListItem은 사용자 정의 함수로 어댑터 안에서 구현하였다.

fun addListItem(listItem: ListInfo) {
        // 배열은 0,1,2,3..으로 쌓이는데 최신 add 정보가 가장 위에 나오게 해야한.다
        // 최신순으로 보이게 하려면 0번째 인덱스의 위치로 add해주면 된다.
        lstTodo.add(0, listItem)
    }

위 코드를 통해서 아이템을 가장 위에 보이게 추가할 수 있다.

리스트 삭제, 수정 이벤트 처리

// TodoViewHolder는 그저 같은 클래스 내부에 작성된 별도의 클래스이므로 inner을 붙임으로써 lstTodo를 사용할 수 있다.
    inner class TodoViewHolder(private val binding: ListItemBinding) : RecyclerView.ViewHolder(binding.root) {
        fun bind(listItem : ListInfo) {
            // 리스트 뷰 데이터를 UI에 연동
            binding.tvContent.setText(listItem.listContent)
            binding.tvDate.setText(listItem.listDate)

            // 리스트 삭제 버튼 클릭 연동
            binding.btnRemove.setOnClickListener {
                // 쓰레기통 이미지 클릭 시 이벤트 처리

                AlertDialog.Builder(binding.root.context)
                    .setTitle("[경고]")
                    .setMessage("제거하시면 데이터는 복구되지 않습니다.\n정말 제거하시겠습니까?")
                    .setPositiveButton("제거", DialogInterface.OnClickListener { dialog, i ->
                        lstTodo.remove(listItem)
                        notifyDataSetChanged()
                        Toast.makeText(binding.root.context, "제거되었습니다.", Toast.LENGTH_SHORT).show()
                    })
                    .setNegativeButton("취소", DialogInterface.OnClickListener { dialog, i ->

                    })
                    .show()
            }

            // 리스트 수정
            binding.root.setOnClickListener {
                val bindingDialog = DialogEditBinding.inflate(LayoutInflater.from(binding.root.context), binding.root, false)
                bindingDialog.etMemo.setText(listItem.listContent)

                 androidx.appcompat.app.AlertDialog.Builder(binding.root.context)
                     .setTitle("오늘의 할 일은 ?")
                     .setView(bindingDialog.root)
                     .setPositiveButton("작성", DialogInterface.OnClickListener { dialog, i ->
                         // 작성 버튼 이벤트 처리
                         listItem.listContent = bindingDialog.etMemo.text.toString()
                         listItem.listDate = SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())
                         // arraylist 수정
                         lstTodo.set(adapterPosition, listItem)
                         notifyDataSetChanged()
                     })
                     .setNegativeButton("취소", DialogInterface.OnClickListener { dialog, i ->
                     // 취소 버튼 이벤트 처리
                     })
                     .show()
            }
        }

    }

작성하기 버튼 구현과 맥락이 비슷하여 비교적 쉽게 이해하려할 수 있을 것이다.

profile
장래희망 : 침대 위 녹아든 치즈

0개의 댓글