Skip to content

5.4. 키워드 선택

JiHwan edited this page Jan 15, 2021 · 8 revisions

구현 방법

✔️ KeywordAddView

Main

  • 입력할 때 다양한 효과를 보여주기 위해 TextInputLayout과 TextInputEditText를 사용

Detail

  • 입력된 텍스트에 공백이 존재하거나, 최대 글자수를 초과하거나, 이미 있는 단어 입력을 했을 때 경고 문구 & 입력 버튼 비활성화를 위해 addTextChangedListener 를 사용

✔️ KeywordPopupView

Main

  • 화면 전환을 위해 viewpager를 사용하였고 TabLayout custom

✔️ KeywordListView

Main

  • 키워드 추가 및 선택, 취소 효과를 내기 위해 chip 사용

Detail

  • chip이 추가되었을 때 추가 버튼이 맨 마지막으로 가게끔 하기 위해 binding.cgMyWord.addView(createChip("추가된 샘플"),binding.cgMyWord.childCount-1)
  • chip을 눌렀을 때 색상이 바뀌게하는 스타일 및 기타 속성 지정을 위해 createChip 함수 작성

구현 코드

✔️ KeywordAddView

📔 activity_keyword_add.xml

<com.google.android.material.textfield.TextInputLayout
                android:id="@+id/et_keyword_input_layout"
                style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="16dp"
                android:layout_marginTop="41dp"
                android:layout_marginRight="16dp"
                android:hint="@string/input_value"
                android:textColorHint="@color/alto"
                app:boxCornerRadiusBottomEnd="15dp"
                app:boxCornerRadiusBottomStart="15dp"
                app:boxCornerRadiusTopEnd="15dp"
                app:boxCornerRadiusTopStart="15dp"
                app:boxStrokeColor="@color/selector_edittext"
                app:boxStrokeErrorColor="@color/persimmon"
                app:errorIconDrawable="@null"
                app:hintTextColor="@color/persimmon"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@id/tv_keyword_guide">

                <com.google.android.material.textfield.TextInputEditText
                    android:id="@+id/et_keyword_input"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:inputType="text"
                    android:maxLength="5"
                    android:maxLines="1"
                    android:privateImeOptions='"defaultInputmode=korean"'
                    android:textCursorDrawable="@drawable/edittext_cursor_cod_gray" />

📔 KeywordAddActivity.kt

       private fun keywordInput() {
        var sameKeyword: String
        binding.etKeywordInput.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                if (binding.etKeywordInput.text.toString().isEmpty()) {
                    binding.btnAdd.isEnabled = false
                    binding.tvErrortext.visibility = View.INVISIBLE
                    binding.btnErrorIcon.visibility = View.INVISIBLE
                } else if (binding.etKeywordInput.length() > 5) {
                    binding.btnAdd.isEnabled = false
                    binding.tvErrortext.visibility = View.VISIBLE
                    binding.btnErrorIcon.visibility = View.VISIBLE
                    binding.tvErrortext.setText(R.string.maximum_five_word)
                } else if (binding.etKeywordInput.text.toString().contains(" ")) {
                    binding.btnAdd.isEnabled = false
                    binding.tvErrortext.visibility = View.VISIBLE
                    binding.btnErrorIcon.visibility = View.VISIBLE
                    binding.tvErrortext.setText(R.string.there_is_space)
                } else if (keywordListForDuplicated.contains(binding.etKeywordInput.text.toString())) {
                    binding.btnAdd.isEnabled = false
                    sameKeyword =
                        "'" + binding.etKeywordInput.text.toString() + "' 은(는) " + getString(R.string.already_exist)
                    binding.tvErrortext.visibility = View.VISIBLE
                    binding.btnErrorIcon.visibility = View.VISIBLE
                    binding.tvErrortext.text = sameKeyword
                } else if (addedMyWord.contains(binding.etKeywordInput.text.toString())) {
                    binding.btnAdd.isEnabled = false
                    sameKeyword =
                        "'" + binding.etKeywordInput.text.toString() + "' 은(는) " + getString(R.string.already_exist)
                    binding.tvErrortext.visibility = View.VISIBLE
                    binding.btnErrorIcon.visibility = View.VISIBLE
                    binding.tvErrortext.text = sameKeyword
                } else if (isKoreanInWord(binding.etKeywordInput.text.toString())) {
                    binding.btnAdd.isEnabled = false
                    binding.tvErrortext.visibility = View.VISIBLE
                    binding.btnErrorIcon.visibility = View.VISIBLE
                    binding.tvErrortext.text = "특수문자, 숫자, 영어를 제외하고 입력해주세요."
                } else {
                    binding.btnAdd.isEnabled = true
                    binding.tvErrortext.visibility = View.GONE
                    binding.btnErrorIcon.visibility = View.GONE
                }
            }

            override fun afterTextChanged(s: Editable?) {}
        })
    }

✔️ KeywordPopupView

📔 activity_keyword_popup.xml

        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tl_keyword_popup"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:tabBackground="@drawable/selector_tab_indicator"
            app:tabGravity="center"
            app:tabIndicator="@null"
            app:tabPaddingEnd="9dp"
            app:tabPaddingStart="9dp"
            android:layout_marginTop="72dp">

            <com.google.android.material.tabs.TabItem
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

            <com.google.android.material.tabs.TabItem
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

            <com.google.android.material.tabs.TabItem
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
        </com.google.android.material.tabs.TabLayout>

        <androidx.viewpager.widget.ViewPager
            android:id="@+id/vp_keyword_popup"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@+id/tv_popup_skip"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tl_keyword_popup" />

📔 KeywordPopupActivity.kt

    private fun viewPagerChange() {
        binding.vpKeywordPopup.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {

            override fun onPageScrolled(
                position: Int,
                positionOffset: Float,
                positionOffsetPixels: Int
            ) {
                btnOnOff()
            }
            override fun onPageSelected(position: Int) {
                btnOnOff()
            }
            override fun onPageScrollStateChanged(state: Int) {
            }
        })
    }

📔 tab_indicator.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true">
        <shape
            android:shape="ring"
            android:innerRadius="0dp"
            android:thickness="3dp"
            android:useLevel="false">
            <solid android:color="#EA644B"/>
        </shape>
    </item>
    <item>
        <shape
            android:shape="ring"
            android:innerRadius="1dp"
            android:thickness="2dp"
            android:useLevel="false">
            <solid android:color="@color/silver"/>
        </shape>
    </item>
</selector>

✔️ KeywordListView

📔 KeywordListActivity.kt

private fun createChip(str: String): Chip {
    val chipDrawable = ChipDrawable.createFromAttributes(
        this,
        null,
        0,
        R.style.Widget_MaterialComponents_Chip_Choice
    )
    return Chip(this).apply {
        text = str
        setChipDrawable(chipDrawable)
        setChipBackgroundColorResource(R.color.selector_chip)
        setTextAppearance(R.style.MyDailyChipTextStyleAppearance)
        setRippleColorResource(android.R.color.transparent)
        setOnClickListener {
            it as Chip
            if (isChecked) { //주황색일 때
                clickedChipCount++
                if (clickedChipCount >= 9) {
                    binding.btnSelectFinish.isEnabled = true
                    it.isChecked = false
                    clickedChipCount--
                    floatingDialog()
                } else if (clickedChipCount == 8) {
                    addKeywordList(it.text as String)
                    binding.btnSelectFinish.isEnabled = true
                } else {
                    addKeywordList(it.text as String)
                    binding.btnSelectFinish.isEnabled = false
                }
            } else {
                clickedChipCount--
                if (clickedChipCount < 8) {
                    binding.btnSelectFinish.isEnabled = false
                }
                removeKeywordList(it.text as String)
            }
        }
    }
}

📔 activity_keyword_list.xml

<com.google.android.material.chip.ChipGroup
	android:id="@+id/cg_my_word"
    android:layout_width="match_parent"
	android:layout_height="wrap_content"
	android:paddingHorizontal="16dp"
	android:layout_marginTop="16dp"
	app:layout_constraintTop_toBottomOf="@id/tv_my_word"
	app:layout_constraintStart_toStartOf="parent"
	app:layout_constraintEnd_toEndOf="parent">

	<com.google.android.material.chip.Chip
		android:id="@+id/chip_add"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		app:chipIcon="@drawable/ic_add"
		app:chipIconSize="32dp"
		app:rippleColor="@android:color/transparent"
		android:stateListAnimator="@null"
		app:chipBackgroundColor="@android:color/transparent"/>

</com.google.android.material.chip.ChipGroup>

실행 화면

KeywordAddView KeywordPopupView KeywordListView
ezgif com-gif-maker (4)
ezgif com-gif-maker (5)
ezgif com-gif-maker (6)